2010-10-08 4 views
3

Мне нужно удалить дублированные строки из базы данных. Могу ли я сделать это с помощью простого sql-запроса? Если нет, пожалуйста, покажите мне какой-нибудь быстрый алгоритм, чтобы сделать это.Удаление дублированных строк из базы данных

Пример:

id| field_one | field_two | 
1 | 0000000 | 11111111 | 
2 | 2222222 | 33333333 | 
3 | 2222222 | 33333333 | 
4 | 4444444 | 55555555 | 

нужно удалить строку с идентификатором 2 (или 3, независимо от того, что они равны между собой, но не оба). Спасибо за любую помощь

ответ

4
delete from the_table where id in 
    (select max(id) from the_table 
     group by field_one, field_two 
     having count(*) > 1) 

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

+0

+1 - Был посреди публикации точно такого же ответа. Скорость подсчитывается! – codingbadger

+1

А если у вас одна и та же строка три раза? – CristiC

+0

Спасибо за супер быстрый ответ :) Это должно сработать. – Scorpil

3

Сначала выберите все различные строки, а затем удалить другие из них:

DELETE FROM MyTable 
WHERE id NOT IN 
     (
     SELECT MAX(id) FROM MyTable 
     GROUP BY field_one, field_two 
    ) 
+0

+1. Это будет работать со строками, дублируемыми более одного раза. Это может быть довольно медленным, хотя, если большинство строк не дублируются. Полагаю, хорошо иметь оба запроса в вашем арсенале и выбирать в соответствии с ситуацией. – Thilo

+0

Другим полезным подходом, когда есть много дубликатов, может быть копирование «хороших» строк в рабочую/промежуточную таблицу, а затем усечение старой. Это позволяет избежать фрагментации. – Thilo

1

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

создать новую таблицу, настроить УНИКАЛЬНЫЙ ИНДЕКС для комбинации столбцов: (field_one, field_two) и скопировать содержимое первой таблицы в новую. Затем вы удалите старый и переименуете новый в имя старой таблицы.

Это все.

2
set rowcount 1 
delete userTbl1 from userTbl1 a1 where (select count(UName) from userTbl1 a2 where a2.UName =a1.UName)>1 
while @@rowcount > 0 
delete userTbl1 from userTbl1 a1 where (select count(UName) from userTbl1 a2 where a2.UName =a1.UName)>1 
set rowcount 0 
Смежные вопросы