Для понимания давайте возьмем простую таблицу Employee с приведенной ниже схемой
EmployeeId - int
EmployeeName varchar(50)
Age int
Позволяет заполнить дублирующиеся значения.Обратите внимание, что первичный ключ не дублируется в этом случае
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (1,'Mark',20)
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (2,'Tom',22)
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (3,'Sam',24)
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (4,'Mark',20)
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (5,'Tom',22)
INSERT INTO Employee(EmployeeId,EmployeeName,Age) VALUES (6,'Tom',22)
GO
, мы можем использовать CTE для поиска дублирующихся строк.Соберите повторяющиеся строки с помощью оператора Group by / Count.Как только дублирующиеся строки идентифицированы, мы выбираем эти строки из основной таблицы, используя условие соединения.Теперь оцените эти строки и удалите все строки, кроме строк с рангом 1. Я считаю это намного более элегантным.
WITH TotalDuplicates(EmployeeName,Age,Total) AS
(
SELECT EmployeeName,Age,COUNT(employeeId) AS Total FROM Employee
GROUP BY EmployeeName,Age
HAVING COUNT(employeeId) > 1
)
,DistinctRows(EmployeeId,EmployeeName,Age) AS
(
SELECT E.EmployeeId,E.EmployeeName,E.Age FROM Employee AS E
INNER JOIN TotalDuplicates AS D
ON (E.EmployeeName = D.EmployeeName AND E.Age = D.Age)
)
,OrderedDuplicateTables(EmployeeId,EmployeeName,Age,Ranking) AS
(
SELECT
EmployeeId,
EmployeeName,
Age,
RANK() OVER (PARTITION BY EmployeeName, Age ORDER BY EmployeeId DESC)
FROM DistinctRows
)
DELETE FROM Employee
WHERE EmployeeId IN (SELECT EmployeeId FROM OrderedDuplicateTables WHERE Ranking > 1)