6

我有一个表格,其中包含IDfirstnamelastnameaddress等列email

有没有办法email从表中删除重复的地址?

附加信息(来自评论):

如果有两行具有相同的email地址,其中一行将是正常的firstnamelastname而另一行将firstname. 因此,我可以区分它们。我只想删除名字为“即时”的那个。

请注意,有些记录firstname='Instant'只有 1 个email地址。我不想只删除一个唯一的电子邮件地址,所以我不能只删除所有firstname='Instant'.

请帮帮我。

4

6 回答 6

10
DELETE n1 FROM customers n1, customers n2 WHERE n1.ID > n2.ID AND n1.email = n2.email
于 2013-10-22T11:46:11.610 回答
6
DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY email)

这会为每封电子邮件保留最低的、第一个插入的 ID。

于 2011-05-09T11:28:16.340 回答
3

虽然 MiPnamic 的回答基本上是正确的,但它并不能解决您保留哪些记录以及丢弃哪些记录(以及您如何整理相关记录)的问题。简短的回答是,这不能以编程方式完成。

给定这样的查询:

SELECT email, MAX(ID), MAX(firstname), MAX(lastname), MAX(address)
FROM customers

更糟糕的是 - 因为您可能会从重复行中选择混合字段。您需要执行以下操作:

SELECT csr2.*
FROM customers csr2
WHERE ID IN (
   SELECT MAX(id)
   FROM customers csr
   GROUP BY email
);

获取一组唯一的现有行。当然,您仍然需要整理所有相关记录(提示 - 这是上面查询未返回的 IDs ni customers 表)。

于 2011-05-09T11:22:16.317 回答
0
  • 复制表结构
  • 在新表的电子邮件上放置一个唯一密钥(为了安全起见)
  • 在新表上执行 INSERT 从旧表中选择数据 按电子邮件地址分组
于 2011-05-09T10:56:15.223 回答
0

我不知道这是否会在 MYSQL 中工作(我没有使用过)......但你应该能够执行以下代码片段之类的操作。

我建议您运行它们以了解是否选择了正确的数据。如果它确实有效,那么您可能想要在列上创建一个约束。

获取所有重复的电子邮件地址:

SELECT 
    EMAILADDRESS, COUNT(1)
FROM
    TABLE
GROUP BY EMAILADDRESS
HAVING COUNT(1) > 1

然后确定给出的ID:

SELECT
    ID
FROM 
    TABLE
WHERE 
    EMAILADDRESS IN (
        SELECT 
            EMAILADDRESS
        FROM
            TABLE
        GROUP BY EMAILADDRESS
        HAVING COUNT(1) > 1
    )

最后,根据上述和其他约束条件删除行:

DELETE 
FROM 
    TABLE
WHERE
    ID IN (
        SELECT
            ID
        FROM 
            TABLE
        WHERE 
            EMAILADDRESS IN (
                SELECT 
                    EMAILADDRESS
                FROM
                    TABLE
                GROUP BY EMAILADDRESS
                HAVING COUNT(1) > 1
            )
    )  
    AND FIRSTNAME = 'Instant'
于 2011-05-09T11:23:14.103 回答
0

使用上面的 forsvarir 答案进行去重的另一种方法,但对其进行了一些修改。这样,您可以保留您选择分区的任何记录:

BEGIN TRAN

DELETE 
FROM   [TABLE]
WHERE
ID IN (
    SELECT a.ID
    
    FROM
    (
        SELECT  ROW_NUMBER() OVER(PARTITION BY Email ORDER BY Email) [RowNum], ID, Email
        FROM    [TABLE]
        WHERE   Email IN 
                (
                    SELECT 
                        Email
                    FROM
                        [TABLE]
                    GROUP BY Email
                    HAVING COUNT(1) > 1
                )
    ) a
    WHERE a.RowNum > 1
)

--COMMIT TRAN
--ROLLBACK TRAN
于 2021-02-08T18:02:33.537 回答