SQL: Suppression d'une ligne dont les valeurs existent déjà

J'ai une table qui ressemble à ceci:

ID | DATE | NAME | VALUE_1 | VALUE_2 1 | 27.11.2015 | Homer | A | B 2 | 27.11.2015 | Bart | C | B 3 | 28.11.2015 | Homer | A | C 4 | 28.11.2015 | Maggie | C | B 5 | 28.11.2015 | Bart | C | B 

Je supprime actuellement les lignes en double (merci à ce fil ) en utilisant ce code:

 WITH cte AS (SELECT ROW_NUMBER() OVER (PARTITION BY [VALUE_1], [VALUE_2] ORDER BY [DATE] DESC) RN FROM [MY_TABLE]) DELETE FROM cte WHERE RN > 1 

Mais ce code ne supprime pas exactement les lignes que je veux. Je voudrais supprimer seulement les lignes dont les valeurs existent déjà donc dans mon exemple je voudrais supprimer seulement la ligne 5 parce que la ligne 2 a les mêmes valeurs et est plus ancienne.

Code pour créer ma table et insert des valeurs:

 CREATE TABLE [t_diff_values] ([id] INT IDENTITY NOT NULL PRIMARY KEY, [date] DATETIME NOT NULL, [name] VARCHAR(255) NOT NULL DEFAULT '', [val1] CHAR(1) NOT NULL DEFAULT '', [val2] CHAR(1) NOT NULL DEFAULT ''); INSERT INTO [t_diff_values] ([date], [name], [val1], [val2]) VALUES ('2015-11-27','Homer', 'A','B'), ('2015-11-27','Bart', 'C','B'), ('2015-11-28','Homer', 'A','C'), ('2015-11-28','Maggie', 'C','B'), ('2015-11-28','Bart', 'C','B'); 

Vous devez append un CTE supplémentaire pour indexer toutes les îles et ensuite appliquer votre logique en double dans le second CTE :

 DECLARE @t TABLE ( ID INT , DATE DATE , VALUE_1 CHAR(1) , VALUE_2 CHAR(1) ) INSERT INTO @t VALUES ( 1, '20151127', 'A', 'B' ), ( 2, '20151128', 'C', 'B' ), ( 3, '20151129', 'A', 'B' ), ( 4, '20151130', 'A', 'B' ); WITH cte1 AS ( SELECT * , ROW_NUMBER() OVER ( ORDER BY date) - ROW_NUMBER() OVER ( PARTITION BY VALUE_1, VALUE_2 ORDER BY DATE) AS gr FROM @t ), cte2 AS ( SELECT * , ROW_NUMBER() OVER ( PARTITION BY VALUE_1, VALUE_2, gr ORDER BY date) AS rn FROM cte1 ) DELETE FROM cte2 WHERE rn > 1 SELECT * FROM @t 

Essaye ça

 CREATE TABLE [dbo].[Employee]( [ID] INT NOT NULL, [Date] DateTime NOT NULL, [VAL1] varchar(20) NOT NULL, [VAL2] varchar(20) NOT NULL ) INSERT INTO [dbo].[Employee] VALUES (1,'2015-11-27 10:44:33.087','A','B') INSERT INTO [dbo].[Employee] VALUES (2,'2015-11-28 10:44:33.087','C','B') INSERT INTO [dbo].[Employee] VALUES (3,'2015-11-29 10:44:33.087','A','B') INSERT INTO [dbo].[Employee] VALUES (4,'2015-11-30 10:44:33.087','A','B') with cte as( select *, rn = row_number() over(partition by [VAL1], [VAL2] ORDER BY [DATE] DESC), cc = count(*) over(partition by [VAL1], [VAL2]) from [Employee] ) delete from cte where rn > 1 and rn < cc select * from [Employee] 

Vous pouvez utiliser cette requête:

 WITH cte AS ( SELECT RN = ROW_NUMBER() OVER (ORDER BY ID) , * FROM @data ) DELETE FROM c1 --SELECT * FROM CTE c1 INNER JOIN CTE c2 ON c1.RN +1 = c2.RN AND c1.VALUE_1 = c2.VALUE_1 AND c1.VALUE_2 = c2.VALUE_2 

Ici, je les command par ID. Si le suivant (RN + 1) a des V1 et V2 similaires, il est supprimé.

Sortie:

 ID DATE VALUE_1 VALUE_2 1 2015-11-27 AB 2 2015-11-28 CB 4 2015-11-30 AB 

Les données:

 declare @data table(ID int, [DATE] date, VALUE_1 char(1), VALUE_2 char(1)); insert into @data(ID, [DATE], VALUE_1, VALUE_2) values (1, '20151127', 'A', 'B'), (2, '20151128', 'C', 'B'), (3, '20151129', 'A', 'B'), (4, '20151130', 'A', 'B');