【问题标题】:Delete Duplicate email addresses from Table in MYSQL从 MYSQL 中的表中删除重复的电子邮件地址
【发布时间】:2021-02-09 02:02:33
【问题描述】:

我有一个表格,其中包含 ID、firstname、lastname、address、email 等列。

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

附加信息(来自 cmets):

如果有两行具有相同的email 地址,其中一行将具有正常的firstname 和lastname,但另一行将在firstname 中具有'Instant'。因此,我可以区分它们。我只想删除名字为“instant”的那个。

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

请帮帮我。

【问题讨论】:

  • 你打算如何处理剩下的行?如果你有两个名字和相同的电子邮件地址,你会怎么做?您是删除两封重复的电子邮件,还是只删除一个?你如何决定哪个?
  • 如果有两个相同的电子邮件地址,一个将具有正常的名字和姓氏,而另一个将在名字中包含“Instant”。因此,我可以区分它们。我只想删除名字为“instant”的那个。
  • 你为什么不直接delete where firstname='Instant'?
  • 但在某些记录中,firstname=Instant 只有一个电子邮件地址,我不想只删除一个唯一的电子邮件地址。这并不意味着对于每个 firstname=Instant 我都会有两个电子邮件地址。

标签: mysql duplicate-removal


【解决方案1】:
DELETE n1 FROM customers n1, customers n2 WHERE n1.ID > n2.ID AND n1.email = n2.email

【讨论】:

    【解决方案2】:
    DELETE FROM table WHERE id NOT IN (SELECT MIN(id) FROM table GROUP BY email)
    

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

    【讨论】:

      【解决方案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 表)。

      【讨论】:

        【解决方案4】:

        我不知道这是否可以在 MYSQL 中使用(我没有使用过)...但是您应该可以执行以下 sn-ps 之类的操作。

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

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

        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'
        

        【讨论】:

        • 谢谢,希望对我有所帮助。最好的!
        • 注意,如果您没有 OP 的“即时”标志,这实际上会删除原件。如果您没有其他方法可以判断“重复”记录是哪条记录,这将无法帮助您进行重复数据删除。
        【解决方案5】:
        • 复制表结构
        • 在新表的电子邮件上放置唯一密钥(为了安全起见)
        • 在新表上执行 INSERT 从旧表中选择数据 按电子邮件地址分组

        【讨论】:

        • 如果你不介意告诉我 mysql 中的步骤来执行所有这 3 个步骤。我只是初学者。
        • 您不能只按电子邮件地址分组。 “select”子句中的所有内容都需要在“group by”子句中。如果说“地址”(表中的另一列)中有一个额外的空间,这将如何工作?您仍然有两行,但第二行将导致插入失败(我希望在同一语句中使用任何其他插入)。这可能会满足 OP 的要求(如果实施正确),但这似乎是一个糟糕的解决方案......
        • 你是对的。我允许重复的电子邮件地址下订单是一种糟糕的编程习惯。现在我觉得他们有问题。
        【解决方案6】:

        使用上面的 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
        

        【讨论】:

          猜你喜欢
          • 2019-12-17
          • 1970-01-01
          • 2012-01-30
          • 2018-05-23
          • 2011-08-26
          • 1970-01-01
          • 1970-01-01
          • 2021-08-29
          • 2015-05-02
          相关资源
          最近更新 更多