Один из вопроса, который задают в интервью, был,
Одна таблица имеет 100 записей. 50 из них являются дубликатами. Действительно ли возможно с единым запросом удалить дублирующиеся записи из таблицы, а также выбрать и отобразить оставление 50 записями.
Действительно ли это возможно в единственном SQL-запросе?
Спасибо
SNA
С 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
. Выход . Выход показывает записи, которые удаляются.
Обновление:
Вышеуказанные запросы будут удалять дубликаты и дать вам строки, которые удаляются, а не строки, которые остаются. Если это важно для вас (все вообще, остальные 50 строк должны быть идентичны 50 удаленным строкам), вы можете использовать SQL Server 2008 Merge синтаксис для достижения этого.
ОТВЕТ ЛИВЕН - это хорошее объяснение того, как выводить удаленные строки. Я хотел бы добавить две вещи:
Если вы хотите сделать что-то большее с выходом, отличным, чем отображение его, вы можете указать вывод в @tbl
(где @tbl
Это таблица-вари, которую вы объявляете до удаления);
с использованием 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
)
звучит вряд ли, по крайней мере, в ANSI SQL, поскольку удаление возвращает только количество удаленных строк.