Самый быстрый SQL-скрипт получения дубликатов

Приведите пример быстрого SQL для получения дубликатов в наборах данных с сотнями тысяч записей. Обычно я использую что-то вроде:

SELECT afield1, afield2 FROM afile a 
WHERE 1 < (SELECT count(afield1) FROM afile b WHERE a.afield1 = b.afield1);

Но это довольно медленно.


person Johan Bresler    schedule 13.10.2008    source источник


Ответы (5)


Это более прямой способ:

select afield1,count(afield1) from atable 
group by afield1 having count(afield1) > 1
person Vinko Vrsalovic    schedule 13.10.2008

Вы можете попробовать:

select afield1, afield2 from afile a
where afield1 in
( select afield1
  from afile
  group by afield1
  having count(*) > 1
);
person Tony Andrews    schedule 13.10.2008
comment
На самом деле это мой предпочтительный способ, потому что вы можете вернуть все столбцы таблицы. - person leek; 13.10.2008
comment
Как ни странно, 2 человека проголосовали за этот ответ, не комментируя, почему. Я так понимаю, это означает, что с ним что-то не так? - person Tony Andrews; 14.10.2008
comment
Да, но он показывает информацию, которую запросил OP: field1 и field2, которые могут быть необходимы, например, для определения, какую строку сохранить. - person Tony Andrews; 16.10.2008
comment
Это медленнее, однако дает вам обе дубликаты записей. - person newdark-it; 07.11.2018

Аналогичный вопрос был задан на прошлой неделе. Там есть хорошие ответы.

SQL для поиска повторяющихся записей (внутри группы)

В этом вопросе ОП интересовали все столбцы (поля) в таблице (файле), но строки принадлежали к одной группе, если они имели одинаковое значение ключа (afield1).

Есть три вида ответов:

подзапросы в предложении where, как и некоторые другие ответы здесь.

внутреннее соединение между таблицей и группами, рассматриваемыми как таблица (мой ответ)

и аналитические запросы (что-то новое для меня).

person Walter Mitty    schedule 13.10.2008

Кстати, если кто-то хочет удалить дубликаты, я использовал это:

delete from MyTable where MyTableID in (
  select max(MyTableID)
  from MyTable
  group by Thing1, Thing2, Thing3
  having count(*) > 1
)
person Magnus Smith    schedule 20.01.2011
comment
Только что заметил, что это удалит только один из дубликатов. Если бы было три строки с одинаковым значением, вам пришлось бы выполнить этот запрос дважды, чтобы исключить все дубликаты. - person Magnus Smith; 24.01.2014

Это должно быть достаточно быстро (даже быстрее, если проиндексированы поля dupeField).

SELECT DISTINCT a.id, a.dupeField1, a.dupeField2
FROM TableX a
JOIN TableX b
ON a.dupeField1 = b.dupeField2
AND a.dupeField2 = b.dupeField2
AND a.id != b.id

Я предполагаю, что единственным недостатком этого запроса является то, что, поскольку вы не выполняете COUNT(*), вы не можете проверить количество раз, что он дублируется, только то, что он появляется более одного раза.

person Simon East    schedule 21.08.2012
comment
Это не очень быстро, когда я пробую это на своем столе. Но у меня нет индекса. - person r_j; 17.04.2013