【问题标题】:Select and display only duplicate records in MySQL只选择并显示 MySQL 中的重复记录
【发布时间】:2012-07-26 13:01:29
【问题描述】:

这个问题很简单,我由于某种原因无法得到正确的结果来只显示重复的记录

Table   : Paypal_ipn_orders
id                              payer_email
1                               susan@gmail.com
2                               ryan@gmail.com   
3                               susan@gmail.com
4                               steve@gmail.com
5                               steve@gmail.com

SELECT id, COUNT( payer_email ) `tot`
FROM paypal_ipn_orders
GROUP BY payer_email
HAVING `tot` >1

样本输出

id       tot
1         2
4         2

预期输出

id       payer_email 
1        susan@gmail.com
3        susan@gmail.com
4        steve@gmail.com
5        steve@gmail.com

我该如何做到这一点?

【问题讨论】:

    标签: mysql duplicates


    【解决方案1】:
    SELECT id, payer_email
    FROM paypal_ipn_orders
    WHERE payer_email IN (
        SELECT payer_email
        FROM paypal_ipn_orders
        GROUP BY payer_email
        HAVING COUNT(id) > 1
    )
    

    sqlfiddle

    【讨论】:

    • 返回 unknown table status: TABLE_TYPE unknown table status: TABLE_TYPEShowing rows 0 - -1 ( 0 total, Query took 39.6457 sec)
    • @user1542036 这与此查询无关。这是正确的(检查 sqlfiddle)。对您的错误进行 Google 搜索。
    • 我唯一发现的是,它似乎是特定版本的 phpmyadmin 的问题?我正在运行 3.4.1,所以升级到最新版本应该可以解决它?
    • 在大表中非常慢。
    • 是的,在大表或复杂查询中速度很慢,我们应该使用连接(内连接)而不是这个
    【解决方案2】:

    IN 在我的情况下太慢了(180 秒)

    所以我改用JOIN(0.3 秒)

    SELECT i.id, i.payer_email
    FROM paypal_ipn_orders i
    INNER JOIN (
     SELECT payer_email
        FROM paypal_ipn_orders 
        GROUP BY payer_email
        HAVING COUNT( id ) > 1
    ) j ON i.payer_email=j.payer_email
    

    【讨论】:

    • 使用 SELECT i.id, i.payer_email FROM paypal_ipn_orders i 否则会显示模棱两可的错误
    【解决方案3】:

    这是一个简单的例子:

    select <duplicate_column_name> from <table_name> group by <duplicate_column_name> having count(*)>=2
    

    它肯定会起作用。 :)

    【讨论】:

    • 这太棒了!
    【解决方案4】:

    从表中获取所有重复行的列表:

    Select * from TABLE1 where PRIMARY_KEY_COLUMN NOT IN ( SELECT PRIMARY_KEY_COLUMN
    FROM TABLE1 
    GROUP BY DUP_COLUMN_NAME having (count(*) >= 1))
    

    【讨论】:

    • 目前最快,但您需要从 count(*) >= 1 中删除“=”,因为它也会采用仅存在一次的 id。
    • 堆栈溢出需要允许 = 在这里完全是错误的。
    • @Incognito - 否,&gt;= 的目的是包含非重复行;然后NOT IN 在有重复项时返回“额外”行。请注意,这与 OP 的请求略有不同,后者将列出每个重复项的两行。如果你做&gt;,那么NOT IN 会给你很多不重复的行。在这种情况下,如果使用生成的 ID 删除重复项,结果将是灾难性的!
    【解决方案5】:

    如果我想为两个行数据选择一个或多个不同或可能相同的列值,上述答案将不起作用

    例如。我想选择用户名,出生日期。但在数据库中,用户名不重复但出生日期重复,则此解决方案将不起作用。

    为此使用此解决方案 需要在同一张表上进行self join/

    SELECT  
        distinct(p1.id),  p1.payer_email , p1.username, p1.birth_date
    
    FROM 
        paypal_ipn_orders AS p1 
    
    INNER JOIN paypal_ipn_orders AS p2 
    
    ON p1.payer_email=p2.payer_email
    
    WHERE 
    
    p1.birth_date=p2.birth_date
    

    以上查询将返回所有具有相同 email_id 和相同出生日期的记录

    【讨论】:

    • 次要问题:用AND 替换WHERE 可能更快,因此过滤在INNER JOIN 期间完成,而不是之后。
    【解决方案6】:

    使用此代码

     SELECT *  
        FROM  paypal_ipn_orders 
        GROUP BY  payer_email  
        HAVING COUNT( payer_email) >1  
    

    【讨论】:

    • 不正确。每个 GROUP BY 值将仅显示一行。如果有三个具有相同的电子邮件会发生什么?这只会列出其中之一。 (如果这种情况很少见,可以再次运行,以捕获任何剩余的重复项。重复直到返回零行。)
    【解决方案7】:
    SELECT id, payer_email FROM paypal_ipn_orders
    WHERE payer_email IN (
        SELECT payer_email FROM papypal_ipn_orders GROUP BY payer_email HAVING COUNT(*) > 1)
    

    【讨论】:

    • 这也返回与其他相同的东西
    【解决方案8】:

    这对我来说是最快的

    SELECT
        primary_key
    FROM
        table_name
    WHERE
        primary_key NOT IN (
            SELECT
                primary_key
            FROM
                table_name
            GROUP BY
                column_name
            HAVING
                COUNT(*) = 1
        );
    

    【讨论】:

    • 这不会给出正确的结果,因为您排除了重复记录更改 NOT IN 到 IN
    • @Abhinavbhardwaj - 我已经测试了这个答案,它有效。 inner SELECT 查找所有未重复列值的键。然后NOT IN 排除那些,从而找到所有重复项。
    【解决方案9】:

    类似于this answer,虽然我使用了一个临时表来代替:

    CREATE TEMPORARY TABLE duplicates (
        SELECT payer_email
        FROM paypal_ipn_orders
        GROUP BY payer_email
        HAVING COUNT(id) > 1
    );
    SELECT id, payer_email
    FROM paypal_ipn_orders AS p
    INNER JOIN duplicates AS d ON d.payer_email=p.payer_email;
    

    【讨论】:

      【解决方案10】:
      SELECT * FROM `table` t1 join `table` t2 WHERE (t1.name=t2.name) && (t1.id!=t2.id)
      

      【讨论】:

      • 你能解释一下你解决这个问题的方法吗?您还可以使用编辑器的代码缩进功能突出显示 SQL(四个空格)。
      【解决方案11】:

      我认为这种方式更简单。输出显示 id 和付款人的电子邮件,其中付款人的电子邮件在此表的多个记录中。结果按 id 排序。

          SELECT id, payer_email
          FROM paypal_ipn_orders
          WHERE COUNT( payer_email )>1
          SORT BY id;
      

      【讨论】:

      • MySQL 响应:不是一个有效的查询:“组函数的无效使用”。如果没有 GROUP BY,像这样使用 COUNT 是没有意义的。
      【解决方案12】:

      试试这个查询:

      SELECT id, COUNT( payer_email ) `tot`
      FROM paypal_ipn_orders
      GROUP BY id
      HAVING `tot` >1
      

      有帮助吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-14
        • 2016-12-10
        • 1970-01-01
        • 1970-01-01
        • 2019-04-25
        • 1970-01-01
        • 2017-05-21
        • 1970-01-01
        相关资源
        最近更新 更多