在MySQL中查找重复记录

时间:2009-05-12 18:24:22

标签: mysql duplicates

我想在MySQL数据库中提取重复记录。这可以通过以下方式完成:

SELECT address, count(id) as cnt FROM list
GROUP BY address HAVING cnt > 1

结果是:

100 MAIN ST    2

我想拉它,以便显示每一行都是重复的。类似的东西:

JIM    JONES    100 MAIN ST
JOHN   SMITH    100 MAIN ST

有关如何做到这一点的任何想法?我试图避免做第一个,然后在代码中用第二个查询查找重复项。

24 个答案:

答案 0 :(得分:649)

关键是重写此查询,以便它可以用作子查询。

SELECT firstname, 
   lastname, 
   list.address 
FROM list
   INNER JOIN (SELECT address
               FROM   list
               GROUP  BY address
               HAVING COUNT(id) > 1) dup
           ON list.address = dup.address;

答案 1 :(得分:337)

SELECT date FROM logs group by date having count(*) >= 2

答案 2 :(得分:193)

为什么不直接加入表格呢?

SELECT a.firstname, a.lastname, a.address
FROM list a
INNER JOIN list b ON a.address = b.address
WHERE a.id <> b.id

如果地址可能存在两次以上,则需要DISTINCT。

答案 3 :(得分:53)

我尝试了为这个问题选择的最佳答案,但它让我感到困惑。我实际上只需要在我的桌子上的一个字段上。以下来自this link的示例对我来说非常好:

SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;

答案 4 :(得分:42)

select `cityname` from `codcities` group by `cityname` having count(*)>=2

这是您要求的类似查询,其200%的工作也很简单。 享受!!!

答案 5 :(得分:35)

使用此查询电子邮件地址查找重复的用户...

SELECT users.name, users.uid, users.mail, from_unixtime(created)
FROM users
INNER JOIN (
  SELECT mail
  FROM users
  GROUP BY mail
  HAVING count(mail) > 1
) dupes ON users.mail = dupes.mail
ORDER BY users.mail;

答案 6 :(得分:21)

这不容易:

SELECT *
FROM tc_tariff_groups
GROUP BY group_id
HAVING COUNT(group_id) >1

答案 7 :(得分:19)

我们可以发现重复项也取决于多个字段。对于这些情况,您可以使用以下格式。

SELECT COUNT(*), column1, column2 
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;

答案 8 :(得分:13)

另一种解决方案是使用表别名,如下所示:

SELECT p1.id, p2.id, p1.address
FROM list AS p1, list AS p2
WHERE p1.address = p2.address
AND p1.id != p2.id

在这种情况下,您真正​​做的就是使用原始列表表,创建两个 p 重新计算表 - p 1 p 2 - 其中,然后在地址列(第3行)上执行连接。第4行确保同一记录在您的结果集中不会多次显示(“重复重复”)。

答案 9 :(得分:11)

查找重复的地址比看起来复杂得多,特别是如果您需要准确性。在这种情况下,MySQL查询是不够的......

我在SmartyStreets工作,我们在那里处理验证和重复数据删除以及其他问题,并且我遇到了类似问题的许多不同挑战。

有几个第三方服务会在列表中标记重复项。仅使用MySQL子查询执行此操作不会考虑地址格式和标准的差异。 USPS(针对美国地址)具有制定这些标准的某些指导原则,但只有少数供应商经过认证可以执行此类操作。

因此,我建议您最好的答案是将表格导出为CSV文件,然后将其提交给有能力的列表处理器。其中一个是LiveAddress,可以在几秒到几分钟内自动完成。它将使用名为“Duplicate”的新字段标记重复行,并在其中标记值Y

答案 10 :(得分:10)

这将在一个表传递中选择重复项,没有子查询。

SELECT  *
FROM    (
        SELECT  ao.*, (@r := @r + 1) AS rn
        FROM    (
                SELECT  @_address := 'N'
                ) vars,
                (
                SELECT  *
                FROM
                        list a
                ORDER BY
                        address, id
                ) ao
        WHERE   CASE WHEN @_address <> address THEN @r := 0 ELSE 0 END IS NOT NULL
                AND (@_address := address ) IS NOT NULL
        ) aoo
WHERE   rn > 1

此查询可以模仿ROW_NUMBER()Oracle中存在的SQL Server

有关详细信息,请参阅我博客中的文章:

答案 11 :(得分:10)

效率不高,但应该有效:

SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
        FROM list AS inner
        WHERE inner.address = outer.address) > 1;

答案 12 :(得分:7)

这也将显示有多少重复项,并将在没有连接的情况下对结果进行排序

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC

答案 13 :(得分:4)

最快的重复删除查询程序:

/* create temp table with one primary column id */
INSERT INTO temp(id) SELECT MIN(id) FROM list GROUP BY (isbn) HAVING COUNT(*)>1;
DELETE FROM list WHERE id IN (SELECT id FROM temp);
DELETE FROM temp;

答案 14 :(得分:4)

就此个人而言,这个问题已经解决了我的问题:

SELECT `SUB_ID`, COUNT(SRV_KW_ID) as subscriptions FROM `SUB_SUBSCR` group by SUB_ID, SRV_KW_ID HAVING subscriptions > 1;

此脚本的作用是显示表中不止一次存在的所有订阅者ID以及找到的重复数。

这是表格列:

| SUB_SUBSCR_ID | int(11)     | NO   | PRI | NULL    | auto_increment |
| MSI_ALIAS     | varchar(64) | YES  | UNI | NULL    |                |
| SUB_ID        | int(11)     | NO   | MUL | NULL    |                |    
| SRV_KW_ID     | int(11)     | NO   | MUL | NULL    |                |

希望它对你有所帮助!

答案 15 :(得分:4)

select * from table_name t1 inner join (select distinct <attribute list> from table_name as temp)t2 where t1.attribute_name = t2.attribute_name

对于你的表格,它将类似于

select * from list l1 inner join (select distinct address from list as list2)l2 where l1.address=l2.address

此查询将为您提供列表中的所有不同地址条目...如果您有任何名称的主键值等,我不确定这将如何工作。

答案 16 :(得分:4)

 SELECT firstname, lastname, address FROM list
 WHERE 
 Address in 
 (SELECT address FROM list
 GROUP BY address
 HAVING count(*) > 1)

答案 17 :(得分:3)

SELECT t.*,(select count(*) from city as tt where tt.name=t.name) as count FROM `city` as t where (select count(*) from city as tt where tt.name=t.name) > 1 order by count desc

城市替换为您的表格。 将名称替换为您的字段名称

答案 18 :(得分:2)

    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))

答案 19 :(得分:0)

Powerlord answer确实是最好的,我建议再做一次更改:使用LIMIT确保db不会超载:

SELECT firstname, lastname, list.address FROM list
INNER JOIN (SELECT address FROM list
GROUP BY address HAVING count(id) > 1) dup ON list.address = dup.address
LIMIT 10

如果没有WHERE和进行连接,使用LIMIT是一个好习惯。从较小的值开始,检查查询的重量,然后增加限制。

答案 20 :(得分:0)

jQuery(document).ready(function() {

  document.getElementById('load').style.visibility = "visible";
  document.getElementById('load').style.width = '100' + '%';
  document.getElementById('load').style.height = '100' + '%';
  document.getElementById('load').style.position = 'initial';
  document.getElementById('load').style.backgroundImage = "url('image/load.gif')";

  jQuery('#load').fadeOut(3000);
});

答案 21 :(得分:0)

要快速查看重复的行,您可以运行一个简单的查询

在这里,我要查询表并列出具有相同user_id,market_place和sku的所有重复行:

$fname

要删除重复的行,您必须确定要删除的行。例如ID较低的人(通常是年龄较大的人)或其他一些日期信息。就我而言,我只想删除较低的ID,因为更新的ID是最新信息。

首先仔细检查是否删除了正确的记录。在这里,我从重复项中选择要删除的记录(通过唯一ID)。

select user_id, market_place,sku, count(id)as totals from sku_analytics group by user_id, market_place,sku having count(id)>1;

然后我运行删除查询以删除重复对象:

select a.user_id, a.market_place,a.sku from sku_analytics a inner join sku_analytics b where a.id< b.id and a.user_id= b.user_id and a.market_place= b.market_place and a.sku = b.sku;

备份,仔细检查,验证,验证备份然后执行。

答案 22 :(得分:0)

我使用以下内容:

SELECT * FROM mytable
WHERE id IN (
  SELECT id FROM mytable
  GROUP BY column1, column2, column3
  HAVING count(*) > 1
)

答案 23 :(得分:-1)

select address from list where address = any (select address from (select address, count(id) cnt from list group by address having cnt > 1 ) as t1) order by address

内部子查询返回具有重复地址的行 外部子查询返回带有重复项的地址的地址列。 外部子查询必须只返回一列,因为它用作操作符的操作数&#39; = any&#39;