Найти дубликаты записей в MySQL

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

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

+547
12 мая '09 в 18:24
источник поделиться
20 ответов

Ключ должен переписать этот запрос так, чтобы он мог использоваться как подзапрос.

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;
+591
12 мая '09 в 18:33
источник

Связанные вопросы


Похожие вопросы

SELECT date FROM logs group by date having count(*) >= 2
+276
19 мар. '12 в 17:57
источник

Почему не просто INNER ПРИСОЕДИНИТЬСЯ к таблице с собой?

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, если адрес может существовать более двух раз.

+186
12 мая '09 в 18:49
источник

Я попробовал лучший ответ, выбранный для этого вопроса, но это несколько смутило меня. Мне на самом деле нужно было только на одном поле из моего стола. Следующий пример из этой ссылки очень хорошо работал у меня:

SELECT COUNT(*) c,title FROM `data` GROUP BY title HAVING c > 1;
+43
08 янв. '14 в 13:45
источник
select `cityname` from `codcities` group by `cityname` having count(*)>=2

Это тот же запрос, который вы запросили, и его 200% -ная работа и легко. Наслаждайтесь!!!

+37
20 июн. '11 в 10:34
источник

Найти дубликатов пользователей по адресу электронной почты с помощью этого запроса...

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;
+32
26 янв. '12 в 0:39
источник

мы можем найти, что дубликаты зависят от более чем одного поля. В этих случаях вы можете использовать формат ниже.

SELECT COUNT(*), column1, column2 
FROM tablename
GROUP BY column1, column2
HAVING COUNT(*)>1;
+16
02 мар. '13 в 7:04
источник

Другим решением будет использование псевдонимов таблицы, например:

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-я строка гарантирует, что одна и та же запись не будет отображаться несколько раз в вашем наборе результатов ( "дублировать дубликаты" ).

+12
14 июн. '12 в 4:14
источник

Поиск дублирующих адресов намного сложнее, чем кажется, особенно если вам нужна точность. В этом случае запроса MySQL недостаточно...

Я работаю в SmartyStreets, где мы обращаемся к валидации и дедупликации и другим материалам, и я видел множество разнообразных проблем с подобными проблемами.

Существует несколько сторонних служб, которые будут отмечать дубликаты в списке для вас. Выполнение этого только с подзапросом MySQL не будет учитывать различия в форматах и ​​стандартах адресов. У USPS (для адреса США) есть определенные рекомендации по составлению этих стандартов, но только несколько поставщиков сертифицированы для выполнения таких операций.

Итак, я бы рекомендовал, что лучшим ответом для вас является экспорт таблицы в CSV файл, например, и отправку его в удобный процессор списка. Одним из таких является LiveAddress, который будет выполнен для вас за несколько секунд до нескольких минут автоматически. Он будет отмечать повторяющиеся строки с новым полем "Дубликат" и значением Y в нем.

+11
25 янв. '12 в 20:00
источник

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

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 мая '09 в 18:36
источник

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

SELECT *
FROM list AS outer
WHERE (SELECT COUNT(*)
        FROM list AS inner
        WHERE inner.address = outer.address) > 1;
+8
12 мая '09 в 18:28
источник

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

SELECT  `Language` , id, COUNT( id ) AS how_many
FROM  `languages` 
GROUP BY  `Language` 
HAVING how_many >=2
ORDER BY how_many DESC
+4
17 мар. '15 в 10:28
источник

Самая быстрая процедура удаления запросов дубликатов:

/* 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;
+4
15 дек. '12 в 4:31
источник
 SELECT firstname, lastname, address FROM list
 WHERE 
 Address in 
 (SELECT address FROM list
 GROUP BY address
 HAVING count(*) > 1)
+4
12 мая '09 в 19:09
источник
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
01 дек. '12 в 12:06
источник

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

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

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

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

| 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 апр. '13 в 10:05
источник
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

Замените город на таблицу. Замените имя на имя своего поля

+3
25 янв. '13 в 5:56
источник
    SELECT *
    FROM (SELECT  address, COUNT(id) AS cnt
    FROM list
    GROUP BY address
    HAVING ( COUNT(id) > 1 ))
+2
12 мая '09 в 18:46
источник

Ответ Powerlord действительно лучший, и я бы порекомендовал еще одно изменение: используйте 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

Хорошая привычка использовать LIMIT, если нет ГДЕ и при создании объединений. Начните с малого значения, проверьте, насколько тяжелен запрос, а затем увеличьте предел.

0
14 янв. '15 в 11:02
источник

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

внутренний подзапрос возвращает строки с повторяющимся адресом, тогда внешний подзапрос возвращает столбец адресов для адреса с дубликатами. внешний подзапрос должен возвращать только один столбец, потому что он используется как операнд для оператора "= any"

-1
02 янв. '15 в 12:55
источник

Посмотрите другие вопросы по меткам или Задайте вопрос