SQL: удалить дубликаты - PullRequest
       1

SQL: удалить дубликаты

0 голосов
/ 21 ноября 2011

Как удалить дубликаты из таблицы, настроенной следующим образом?

unique_ID | worker_ID | date | type_ID

Работник может иметь несколько идентификаторов type_ID, связанных с ними, и я хочу удалить дубликаты типов. Если есть дубликат, я хочу удалить тип с самой последней записью.

Ответы [ 4 ]

10 голосов
/ 21 ноября 2011

Кандидат в учебники для оконной функции row_number ():

;WITH x AS (
    SELECT unique_ID
          ,row_number() OVER (PARTITION BY worker_ID,type_ID ORDER BY date) AS rn
    FROM   tbl
    )
DELETE FROM tbl
FROM   x
WHERE  tbl.unique_ID = x.unique_ID
AND    x.rn > 1

Это также учитывает ситуацию, когда набор дубликатов на (worker_ID,type_ID) имеет одинаковые date.
См.упрощенная демонстрация для данных. SE .

Обновление с более простой версией

Оказывается, это можно упростить: в SQL Server вы можете удалить из CTE напрямую:

;WITH x AS (
    SELECT unique_ID
          ,row_number() OVER (PARTITION BY worker_ID,type_ID ORDER BY date) AS rn
    FROM   tbl
    )
DELETE x
WHERE  rn > 1
2 голосов
/ 21 ноября 2011
DELETE FROM @t WHERE unique_Id IN 
(
    SELECT unique_Id FROM 
    (   
        SELECT  unique_Id
                ,Type_Id 
                ,ROW_NUMBER() OVER (PARTITION BY worker_Id, type_Id ORDER BY date) AS rn 
        FROM @t 
    ) Q 
    WHERE rn > 1
)

И чтобы проверить ...

DECLARE @t TABLE
(
    unique_ID  INT IDENTITY,
    worker_ID  INT,
    date  DATETIME,
    type_ID INT
)

INSERT INTO @t VALUES (1, DATEADD(DAY, 1, GETDATE()), 1)
INSERT INTO @t VALUES (1, GETDATE(), 1)
INSERT INTO @t VALUES (2, GETDATE(), 1)
INSERT INTO @t VALUES (1, DATEADD(DAY, 2, GETDATE()), 1)
INSERT INTO @t VALUES (1, DATEADD(DAY, 3, GETDATE()), 2)

SELECT * FROM @t

DELETE FROM @t WHERE unique_Id IN 
(
    SELECT unique_Id FROM 
    (   
        SELECT  unique_Id
                ,Type_Id 
                ,ROW_NUMBER() OVER (PARTITION BY worker_Id, type_Id ORDER BY date) AS rn 
        FROM @t 
    ) Q 
    WHERE rn > 1
)

SELECT * FROM @t

2 голосов
/ 21 ноября 2011
delete from table t
 where exists ( select 1 from table t2 
                 where t2.worker_id = t.worker_id
                   and t2.type_id = t.type_id
                   and t2.date < t.date )

HTH

1 голос
/ 21 ноября 2011

Вы можете использовать этот запрос

delete from worker where unique_id in (
select max(unique_id)  from worker group by  worker_ID , type_ID having count(type_id)>1)

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...