Каков наилучший способ удалить повторяющиеся строки из довольно большой SQL Server
таблицы (т.е. 300 000+ строк)?
Строки, конечно, не будут идеальными дубликатами из-за существования поля RowID
идентичности.
MyTable
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
sql-server
tsql
duplicates
Seibar
источник
источник
DELETE FROM
напрямую использовать термин CTE. См. Stackoverflow.com/q/18439054/398670ROWID()
функцию на столбец RowID, если есть)Ответы:
Предполагая , что не аннулирует, то
GROUP BY
уникальные колонны, и RowId как ряд , чтобы сохранить. Затем просто удалите все, что не имеет идентификатора строки:SELECT
MIN (or MAX)
Если у вас есть GUID вместо целого числа, вы можете заменить
с
источник
DELETE FROM MyTable WHERE RowId NOT IN (SELECT MIN(RowId) FROM MyTable GROUP BY Col1, Col2, Col3);
LEFT JOIN
является менее эффективным , чемNOT EXISTS
sqlinthewild.co.za/index.php/2010/03/23/... Тот же сайт также сравниваетNOT IN
противNOT EXISTS
. sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in Из трех я считаю, чтоNOT EXISTS
работает лучше всего. Все три создадут план с самостоятельным объединением, хотя этого можно избежать.DELETE MyTable FROM MyTable
правильный синтаксис? Я не вижу размещения имени таблицы сразу послеDELETE
опции в документации здесь . Извините, если это очевидно для других; Я новичок в SQL, просто пытаюсь учиться. Что важнее, чем почему это работает: в чем разница между включением имени таблицы или нет?Другой возможный способ сделать это
Я использую
ORDER BY (SELECT 0)
выше, поскольку это произвольно, какой ряд сохранить в случае ничьей.Чтобы сохранить последнюю
RowID
версию, например, вы можете использоватьORDER BY RowID DESC
Планы выполнения
План выполнения для этого часто проще и эффективнее, чем в принятом ответе, поскольку не требует самостоятельного соединения.
Однако это не всегда так. Единственное место, где
GROUP BY
решение может быть предпочтительным, - это ситуации, когда хеш-агрегат будет выбран предпочтительнее, чем агрегат потока.ROW_NUMBER
Решение всегда будет давать в значительной степени тот же план , тогда какGROUP BY
стратегия является более гибкой.Факторы, которые могут благоприятствовать подходу хеш-агрегирования
В крайних версиях этого второго случая (если существует очень мало групп с множеством дубликатов в каждой), можно также рассмотреть возможность просто вставить строки, чтобы сохранить их в новую таблицу, а затем
TRUNCATE
- оригинал и скопировать их обратно, чтобы минимизировать ведение журнала по сравнению с удалением очень высокая пропорция рядов.источник
uniqueidentifier
. Этот намного проще и отлично работает на любом столе. Спасибо Мартин.RowId
) для сравнения.На сайте поддержки Microsoft есть хорошая статья об удалении дубликатов . Это довольно консервативно - они заставляют вас делать все в отдельных шагах - но это должно хорошо работать с большими столами.
Я использовал для этого самостоятельные объединения в прошлом, хотя, вероятно, это можно было бы с помощью предложения HAVING:
источник
Следующий запрос полезен для удаления повторяющихся строк. Таблицы в этом примере , имеют в
ID
качестве столбца идентификации , а столбцы , которые имеют дублирующие данные являютсяColumn1
,Column2
иColumn3
.Следующий скрипт показывает использование
GROUP BY
,HAVING
,ORDER BY
в одном запросе, и возвращает результаты с повторяющимся столбца и его подсчета.источник
NOT IN
часто работает лучше, чемOUTER JOIN ... NULL
. Я хотел бы добавитьHAVING MAX(ID) IS NOT NULL
к запросу, хотя семантически это не должно быть необходимым, поскольку это может улучшить примерPostgres:
источник
источник
Это удалит повторяющиеся строки, кроме первой строки
См. ( Http://www.codeproject.com/Articles/157977/Remove-Duplicate-Rows-from-a-Table-in-SQL-Server )
источник
Я бы предпочел CTE для удаления повторяющихся строк из таблицы сервера SQL
Настоятельно рекомендуем следовать этой статье :: http://codaffection.com/sql-server-article/delete-duplicate-rows-in-sql-server/
источник
Чтобы получить дубликаты строк:
Чтобы удалить дубликаты строк:
источник
DELETE FROM
, во-вторых, это не будет работать, потому что вы не можетеSELECT
из той же таблицы, из которой вы работаетеDELETE
. В MySQL это взрываетсяMySQL error 1093
.Быстро и грязно удалить точно дублированные строки (для небольших таблиц):
источник
Я предпочитаю решение подзапроса \ имеющее count (*)> 1 для внутреннего объединения, потому что мне было легче читать, и было очень легко превратиться в оператор SELECT, чтобы проверить, что будет удалено, прежде чем вы его запустите.
источник
MAX(id)
исключить последние дубликаты, и добавилLIMIT 1000000
к внутреннему запросу, чтобы не пришлось сканировать всю таблицу. Это показало прогресс намного быстрее, чем другие ответы, которые, казалось бы, зависали часами. После того, как таблица была сокращена до управляемого размера, вы можете закончить с другими запросами. Совет: убедитесь, что col1 / col2 / col3 имеют индексы для группировки по.источник
Я думал, что поделюсь своим решением, так как оно работает при особых обстоятельствах. В моем случае таблица с дублирующимися значениями не имела внешнего ключа (потому что значения были продублированы из другой базы данных).
PS: при работе над такими вещами я всегда использую транзакцию, это не только гарантирует, что все выполняется в целом, но и позволяет мне тестировать, не рискуя ничем. Но, конечно, вы все равно должны сделать резервную копию, чтобы быть уверенным ...
источник
Этот запрос показал очень хорошую производительность для меня:
он удалил 1M строк за чуть более 30 секунд из таблицы 2M (50% дубликатов)
источник
Используя CTE. Идея состоит в том, чтобы объединить один или несколько столбцов, которые образуют дублирующуюся запись, а затем удалить то, что вам нравится:
источник
Еще одно простое решение можно найти по ссылке, вставленной здесь . Это легко понять и кажется эффективным для большинства подобных проблем. Это для SQL Server, но используемая концепция более чем приемлема.
Вот соответствующие части со связанной страницы:
Рассмотрим эти данные:
Итак, как мы можем удалить эти дубликаты данных?
Сначала вставьте столбец идентификаторов в эту таблицу, используя следующий код:
Используйте следующий код, чтобы решить это:
источник
ROW_NUMBER
Версия отлично подходит для этого случая, не нужно вдаваться в подробности добавления нового столбца перед началом.Вот еще одна хорошая статья по удалению дубликатов .
Здесь обсуждается, почему это сложно: « SQL основан на реляционной алгебре, и дубликаты не могут возникать в реляционной алгебре, потому что дубликаты не допускаются в наборе ».
Решение временной таблицы и два примера mysql.
В будущем вы собираетесь предотвратить это на уровне базы данных или с точки зрения приложения. Я бы предложил уровень базы данных, потому что ваша база данных должна отвечать за поддержание ссылочной целостности, разработчики просто вызовут проблемы;)
источник
Да, конечно. Используйте временную таблицу. Если вам нужен один, не очень производительный оператор, который «работает», вы можете использовать:
По сути, для каждой строки в таблице подвыбор находит верхний RowID всех строк, которые в точности соответствуют рассматриваемой строке. Таким образом, вы получите список RowID, которые представляют «оригинальные» недублированные строки.
источник
У меня была таблица, где мне нужно было сохранить неповторяющиеся строки. Я не уверен в скорости или эффективности.
источник
HAVING COUNT(*) > 1
?Использовать этот
источник
Другой способ - создать новую таблицу с такими же полями и уникальным индексом . Затем переместите все данные из старой таблицы в новую таблицу . Автоматически SQL SERVER игнорирует (есть также вариант, что делать, если будет повторяющееся значение: игнорировать, прерывать или sth) повторяющихся значений. Итак, у нас одна и та же таблица без повторяющихся строк. Если вы не хотите уникальный индекс, после передачи данных вы можете удалить его .
Специально для больших таблиц вы можете использовать DTS (пакет SSIS для импорта / экспорта данных), чтобы быстро перенести все данные в вашу новую уникально проиндексированную таблицу. Для 7 миллионов подряд это займет всего несколько минут.
источник
Используя приведенный ниже запрос, мы можем удалить дубликаты записей на основе одного или нескольких столбцов. ниже запрос удаляется на основе двух столбцов. Имя таблицы:
testing
и имена столбцовempno,empname
источник
Создать новую пустую таблицу с той же структурой
Выполнить запрос, как это
Затем выполните этот запрос
источник
Это самый простой способ удалить дубликат записи
http://askme.indianyouth.info/details/how-to-dumplicate-record-from-table-in-using-sql-105
источник
Я хотел бы упомянуть этот подход, а также то, что он может быть полезным и работает на всех серверах SQL: довольно часто есть только один - два дубликата, и известны идентификаторы и количество дубликатов. В этом случае:
источник
Я не знаю, насколько хорошо это будет работать, но я думаю, что вы могли бы написать триггер для обеспечения этого, даже если вы не можете сделать это напрямую с индексом. Что-то вроде:
Кроме того, varchar (2048) звучит для меня подозрительно (некоторые вещи в жизни имеют размер 2048 байт, но это довольно редко); разве это не должно быть varchar (max)?
источник
Еще один способ сделать это: -
источник
источник
источник
Если вы хотите просмотреть строки, которые вы собираетесь удалить, и сохранить контроль над тем, какие из повторяющихся строк оставить. Смотрите http://developer.azurewebsites.net/2014/09/better-sql-group-by-find-duplicate-data/
источник