2013-06-26 27 views
3

Пожалуйста, рассмотрим сценарий нижеУдалить дубликат записи SQL Server

У меня есть таблица, как показано ниже

Tag | Id | Client | ....and more columns 
c  30 X 
c  40 Y 
c  50 X 
c  60 A 
c  30 B 
c  40 C 
d  50 D 
d  70 E 
d  80 X 
d  90 Z 
i  30 X 
i  90 Z 
i 100 X 
i  40 M 

Я хочу, чтобы выбрать записи из таблицы таким образом, что если тег = я строку ниже получает удалены из результатов

i  30 X 
    i  90 Z 

Это потому, что строка с id = 90 уже появилась с тегом = d и client = Z. Но ряд

i  40 M 

не должны быть удалены, даже если идентификатор = 40 уже появился с клиентом = C, поскольку значение столбца клиента различны.

DELETE FROM myTable 
WHERE tag=i AND id IN(SELECT id FROM myTable t1 
         INNER JOIN myTable t2 
         ON t1.id=t2.id 
         WHERE tag=d or tag=c) 
+0

Почему «i 100 X» удаляется? –

+0

Я обновил его. 'I 30 X' необходимо удалить –

ответ

3

Вы можете использовать следующие CTE с ROW_NUMBER для обнаружения и удаления дубликатов в соответствии с вашим правилом:

WITH CTE AS 
(
    SELECT [Tag], [Id], [Client], 
    RN=ROW_NUMBER()OVER(PARTITION BY [Id], [Client] ORDER BY [Tag]) 
    FROM dbo.Tags 
) 
DELETE FROM CTE 
WHERE RN > 1 
AND [Tag] = @Tag; 

DEMO

Удаляет следующие записи:

TAG ID CLIENT RN 
i  30  X  2 
i  90  Z  2 

Over Clause

1

Это должно сделать трюк ...

declare @Tag as varchar(10) 
set @Tag = 'i' 

    -- The select statement to view the record to be deleted 
    select MyTable.Tag,MyTable.Id,MyTable.Client,RecordToDelete.totalCount from [SampleDB].dbo.[MyTable] 
    inner join 
    (
    SELECT 
     [Id] 
     ,[Client], 
     TotalCount = count(id) 
    FROM [SampleDB].dbo.[MyTable] 
    group by id,Client 
) as RecordToDelete 
    on RecordToDelete.Id=MyTable.Id and RecordToDelete.Client =MyTable.Client 
    where RecordToDelete.totalCount>1 and MyTable.Tag = @Tag 


    -- The delete statement 
    delete [SampleDB].dbo.[MyTable] 
    where MyTable.Tag = @Tag and MyTable.Id in (
     --select MyTable.Tag,MyTable.Id,MyTable.Client,RecordToDelete.totalCount from [SampleDB].dbo.[MyTable] 
     select MyTable.Id from [SampleDB].dbo.[MyTable] 
     inner join 
     (
     SELECT 
      [Id] 
      ,[Client], 
      TotalCount = count(id) 
     FROM [SampleDB].dbo.[MyTable] 
     group by id,Client 
    ) as RecordToDelete 
     on RecordToDelete.Id=MyTable.Id and RecordToDelete.Client =MyTable.Client 
     where RecordToDelete.totalCount>1 and MyTable.Tag = @Tag 
) 
1

Вы можете попробовать это:

 
DELETE FROM DUU 
WHERE EXISTS 
(
    SELECT TAG,ID,CLIENT FROM 
    (
     SELECT TAG,ID,CLIENT FROM DUU A WHERE TAG IN ('I') AND EXISTS (
     SELECT TAG,ID,CLIENT FROM DUU B WHERE TAG IN ('C') AND A.ID=B.ID AND A.CLIENT=B.CLIENT) 
     UNION 
     SELECT TAG,ID,CLIENT FROM DUU A WHERE TAG IN ('I') AND EXISTS (
     SELECT TAG,ID,CLIENT FROM DUU B WHERE TAG IN ('D') AND A.ID=B.ID AND A.CLIENT=B.CLIENT) 
    ) C WHERE DUU.TAG=C.TAG AND DUU.ID= C.ID AND DUU.CLIENT = C.CLIENT 
) 

Примечание: дуу это имя таблицы.