Один запрос для удаления и отображения дубликатов записей - PullRequest
5 голосов
/ 28 января 2010

Один из вопросов, заданных в интервью, был

В одной таблице 100 записей. 50 из них являются дубликатами. Возможно ли с одним запрос на удаление дубликатов записей из таблицы, а также выберите и отобразить оставшиеся 50 записей.

Возможно ли это в одном запросе SQL?

Спасибо

SNA

Ответы [ 3 ]

6 голосов
/ 28 января 2010

с SQL Server вы бы использовали что-то вроде этого

DECLARE @Table TABLE (ID INTEGER, PossibleDuplicate INTEGER)

INSERT INTO @Table VALUES (1, 100)
INSERT INTO @Table VALUES (2, 100)
INSERT INTO @Table VALUES (3, 200)
INSERT INTO @Table VALUES (4, 200)

DELETE FROM @Table
OUTPUT Deleted.*
FROM  @Table t
      INNER JOIN (
        SELECT    ID = MAX(ID)
        FROM      @Table
        GROUP BY  PossibleDuplicate
        HAVING    COUNT(*) > 1
      ) d ON d.ID = t.ID

Оператор OUTPUT показывает удаляемые записи.

Обновление:

Выше запрос удалит дубликаты и даст вам строки, которые удаляются, а не строки, которые остаются. Если это важно для вас (в целом, оставшиеся 50 строк должны быть идентичны 50 удаленным строкам), вы можете использовать синтаксис SQL Server 2008 MERGE для достижения этого.

1 голос
/ 28 января 2010

Ответ Ливена - хорошее объяснение того, как вывести удаленные строки. Я хотел бы добавить две вещи:

  1. Если вы хотите сделать что-то большее с выводом, отличным от его отображения, вы можете указать OUTPUT INTO @Tbl (где @Tbl - это табличная переменная, которую вы объявляете до удаления);

  2. Использование MAX, MIN или любых других агрегатов может обрабатывать только одну повторяющуюся строку на группу. Если для вас может быть много дубликатов, вам поможет следующий код SQL Server 2005+:

;WITH Duplicates AS
(
    SELECT
        ID,
        ROW_NUMBER() OVER (PARTITION BY DupeColumn ORDER BY ID) AS RowNum
)
DELETE FROM MyTable
OUTPUT deleted.*
WHERE ID IN
(
    SELECT ID
    FROM Duplicates
    WHERE RowNum > 1
)
0 голосов
/ 28 января 2010

Звучит маловероятно, по крайней мере в ANSI SQL, поскольку удаление возвращает только количество удаленных строк.

...