Как заставить код T-SQL находить дубликаты?

В MS Access есть кнопка для генерации кода sql для поиска повторяющихся строк. Я не знаю, есть ли это в SQL Server 2005/2008 Managment Studio.

  1. Если есть, то укажите где

  2. Если это не так, скажите, пожалуйста, как мне получить помощника T-SQL для создания такого кода.


person Jader Dias    schedule 03.08.2009    source источник


Ответы (5)


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

Однако вот как создать SQL для получения дубликатов по набору столбцов:

SELECT col1, col2, col3, col4
FROM table
GROUP BY col1, col2, col3, col4
HAVING COUNT(*) > 1

Это найдет строки, которые для столбцов col1-col4 имеют одну и ту же комбинацию значений более одного раза.

Например, в следующей таблице строки 2+3 будут повторяться:

PK    col1    col2    col3    col4    col5
1       1       2       3       4      6
2       1       3       4       7      7
3       1       3       4       7      10
4       2       3       1       4      5

Две строки имеют общие значения в столбцах col1-col4 и, таким образом, в соответствии с этим SQL считаются дубликатами. Разверните список столбцов, чтобы он содержал все столбцы, для которых вы хотите это проанализировать.

person Lasse V. Karlsen    schedule 03.08.2009
comment
Вы правы, потому что код не такой сложный, как я ожидал. В других языках SQL кодировать вручную может быть сложно. - person Jader Dias; 03.08.2009
comment
Не должно быть, это стандартный SQL, ничего особенного для T-SQL. То же самое должно быть для MySQL, SQLite, Oracle, Sybase, DB2 и т. д. - person Lasse V. Karlsen; 03.08.2009
comment
Ты прав. Отсутствие подсветки синтаксиса и зашумленный код заставили меня поверить, что сгенерированный MS Access код трудно понять, и я даже не пытался раньше. - person Jader Dias; 03.08.2009
comment
Как бы вы удалили только одну из дублированных записей из этого sql? - person K_McCormic; 21.06.2013

Если вы используете SQL Server 2005+, вы можете использовать следующий код, чтобы увидеть все строки вместе с другими столбцами:

SELECT *, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ORDER BY (SELECT 0)) AS DuplicateRowNumber
FROM table

Вы также можете удалить (или иным образом работать с) дубликаты, используя эту технику:

WITH cte AS
(SELECT *, ROW_NUMBER() OVER (PARTITION BY col1, col2, col3, col4 ORDER BY (SELECT 0)) AS DuplicateRowNumber
    FROM table
)
DELETE FROM cte WHERE DuplicateRowNumber > 1

ROW_NUMBER чрезвычайно мощен — с ним можно многое сделать — см. статью о BOL по адресу http://msdn.microsoft.com/en-us/library/ms186734.aspx

person Mike DeFehr    schedule 04.08.2009
comment
+1 за то, что научили нас удалять. Кроме того, ваш фрагмент также включает PK. /некро - person theTuxRacer; 30.07.2012
comment
Еще одним преимуществом является то, что он работает быстрее, чем группа подходов, которые я видел. - person ; 31.07.2015

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

SELECT * FROM db WHERE col IN
    (SELECT col FROM db GROUP BY col HAVING COUNT(*) > 1)
    ORDER BY col
person Ferruccio    schedule 17.04.2014
comment
Я получаю неверное имя столбца, можем ли мы получить список столбцов из метаданных? Сообщение 207, уровень 16, состояние 1, строка 1. Недопустимое имя столбца «col». Сообщение 207, уровень 16, состояние 1, строка 2 Недопустимое имя столбца 'col'. Сообщение 207, уровень 16, состояние 1, строка 2 Недопустимое имя столбца 'col'. Сообщение 207, уровень 16, состояние 1, строка 3. Недопустимое имя столбца «col». - person Blocks; 24.04.2019

АФАИК, это не так. Просто сделайте оператор select, сгруппировав его по всем полям таблицы и отфильтровав с помощью предложения hasing, где количество больше 1.

Если ваши строки дублируются, за исключением ключа, не включайте ключ в поля выбора.

person eKek0    schedule 03.08.2009

Другой способ сделать это — соединить таблицу с самой собой.

SELECT *
FROM dbo.TableA aBase
JOIN dbo.TableA aDupes ON aDupes.ColA = aBase.ColA AND
                          aDupes.ColB = aBase.ColB
WHERE aBase.Pkey < aDupes.Pkey

Примечание. Ключ aBase.Pkey ‹ aDupes.Pkey существует потому, что присоединение таблицы против себя создаст две строки на совпадение, поскольку условие всегда будет выполняться дважды.

Другими словами: если в таблице aBase есть строка, равная строке из aDupes (на основе ColA и ColB), отражение этого совпадения также будет верным — что aDupes имеет строку, равную строке aBase на основе ColA и ColB. Поэтому оба этих совпадения будут возвращены в наборе результатов.

Сузьте это/устраните это отражение, произвольно выбрав все результаты, где одна из таблиц имеет более низкий ключ.

‹ или > не имеет значения, если используются разные ключи.

Это также обеспечивает фильтрацию совпадений со строкой самой по себе, поскольку aBase.Pkey ‹ aDupes.Pkey заставляет первичные ключи отличаться.

person boylec1986    schedule 12.02.2019