Найти дубликаты записей в MySQL - PullRequest
613 голосов
/ 12 мая 2009

Я хочу вытащить дубликаты записей в базе данных 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

Есть мысли о том, как это можно сделать? Я стараюсь не делать первый, а затем искать дубликаты со вторым запросом в коде.

Ответы [ 22 ]

10 голосов
/ 12 мая 2009

Это позволит выбрать дубликаты за один проход таблицы, без подзапросов.

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

Подробности смотрите в статье в моем блоге:

10 голосов
/ 12 мая 2009

Не будет очень эффективным, но оно должно работать:

SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
        FROM list AS inner
        WHERE inner.address = outer.address) > 1;
7 голосов
/ 17 марта 2015

Это также покажет вам, сколько дубликатов есть, и упорядочит результаты без объединений

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC
4 голосов
/ 01 декабря 2012
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

Этот запрос выдаст вам все отдельные записи адресов в таблице списка ... Я не уверен, как это будет работать, если у вас есть какие-либо значения первичного ключа для имени и т. Д.

4 голосов
/ 12 апреля 2013

Лично этот запрос решил мою проблему:

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

Этот скрипт показывает все идентификаторы абонента, которые существуют более одного раза, в таблице и количество найденных дубликатов.

Это столбцы таблицы:

| 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    |                |

Надеюсь, вам это тоже пригодится!

4 голосов
/ 12 мая 2009
 SELECT firstname, lastname, address FROM list
 WHERE 
 Address in 
 (SELECT address FROM list
 GROUP BY address
 HAVING count(*) > 1)
4 голосов
/ 15 декабря 2012

Процедура удаления самых быстрых дубликатов:

/* 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;
3 голосов
/ 25 января 2013
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

Замените город таблицей. Замените name именем вашего поля

2 голосов
/ 12 мая 2009
    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))
0 голосов
/ 09 февраля 2018
    Find duplicate Records:

    Suppose we have table : Student 
    student_id int
    student_name varchar
    Records:
    +------------+---------------------+
    | student_id | student_name        |
    +------------+---------------------+
    |        101 | usman               |
    |        101 | usman               |
    |        101 | usman               |
    |        102 | usmanyaqoob         |
    |        103 | muhammadusmanyaqoob |
    |        103 | muhammadusmanyaqoob |
    +------------+---------------------+

    Now we want to see duplicate records
    Use this query:


   select student_name,student_id ,count(*) c from student group by student_id,student_name having c>1;

+--------------------+------------+---+
| student_name        | student_id | c |
+---------------------+------------+---+
| usman               |        101 | 3 |
| muhammadusmanyaqoob |        103 | 2 |
+---------------------+------------+---+
...