Puis-je supprimer les duplicates de database en fonction de plusieurs colonnes?

J'ai posé cette question il y a quelques time pour supprimer les loggings en double basés sur une colonne. La réponse a bien fonctionné:

delete from tbl where id NOT in ( select min(id) from tbl group by sourceid ) 

J'ai maintenant une situation simillar mais la définition de l'logging en double est basée sur plusieurs colonnes. Comment puis-je modifier ce SQL ci-dessus pour identifier les loggings en double où un logging unique est défini comme concaténé de Col1 + Col2 + Col3. Est-ce que je ferais juste quelque chose comme ça?

 delete from tbl where id NOT in ( select min(id) from tbl group by col1, col2, col3 ) 

Cela montre les lignes que vous voulez conserver:

 ;WITH x AS ( SELECT col1, col2, col3, rn = ROW_NUMBER() OVER (PARTITION BY col1, col2, col3 ORDER BY id) FROM dbo.tbl ) SELECT col1, col2, col3 FROM x WHERE rn = 1; 

Cela montre les lignes que vous voulez supprimer:

 ;WITH x AS ( SELECT col1, col2, col3, rn = ROW_NUMBER() OVER (PARTITION BY col1, col2, col3 ORDER BY id) FROM dbo.tbl ) SELECT col1, col2, col3 FROM x WHERE rn > 1; 

Et une fois que vous êtes satisfait que les deux sets ci-dessus sont corrects, les éléments suivants les supprimeront réellement:

 ;WITH x AS ( SELECT col1, col2, col3, rn = ROW_NUMBER() OVER (PARTITION BY col1, col2, col3 ORDER BY id) FROM dbo.tbl ) DELETE x WHERE rn > 1; 

Notez que dans les trois requêtes, les 6 premières lignes sont identiques et seule la requête suivante après le CTE a changé.

Essaye celui-là. J'ai créé une table tblA avec trois colonnes.

 CREATE TABLE tblA ( id int IDENTITY(1, 1), colA int, colB int, colC int ) 

Et ajouté quelques valeurs en double.

 INSERT INTO tblA VALUES (1, 2, 3) INSERT INTO tblA VALUES (1, 2, 3) INSERT INTO tblA VALUES (4, 5, 6) INSERT INTO tblA VALUES (7, 8, 9) INSERT INTO tblA VALUES (7, 8, 9) 

Si vous remplacez la sélection par une suppression dans l'instruction ci-dessous, votre suppression de plusieurs colonnes fonctionnera.

 SELECT MIN(Id) as id FROM ( SELECT COUNT(*) as aantal, a.colA, a.colB, a.colC FROM tblA a INNER JOIN tblA b ON b.ColA = a.ColA AND b.ColB = a.ColB AND b.ColC = a.ColC GROUP BY a.id, a.colA, a.colB, a.colC HAVING COUNT(*) > 1 ) c INNER JOIN tblA d ON d.ColA = c.ColA AND d.ColB = c.ColB AND d.ColC = c.ColC GROUP BY d.colA, d.colB, d.colC