De eenvoudigste manier is met een CTE (common table expression). Ik gebruik deze methode wanneer ik onbewerkte gegevens moet importeren; het eerste wat ik doe om het te ontsmetten, is ervoor te zorgen dat er geen duplicaten zijn --- dat ik een soort uniek handvat voor elke rij heb.
Samenvatting:
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY [dupe-column-list] ORDER BY [dupe-column-list]) AS _dupe_num FROM [table-name] WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
In het gedeelte "dupe-column-list" vermeldt u alle betrokken kolommen waarvan u wilt dat de waarden uniek zijn. De ORDER BY is waar u beslist, binnen een reeks duplicaten, welke rij "wint" en welke wordt verwijderd. (De "WHERE 1=1" is slechts een persoonlijke gewoonte.)
De reden dat het werkt, is omdat Sql Server een interne, unieke verwijzing bewaart naar elke bronrij die is geselecteerd in de CTE. Dus wanneer de DELETE wordt uitgevoerd, weet deze de exacte rij die moet worden verwijderd, ongeacht wat u in de selectielijst van uw CTE plaatst. (Als je nerveus bent, zou je de "VERWIJDEREN" kunnen veranderen in "SELECTEER *", maar aangezien je dubbele rijen hebt, zal het niet helpen; als je elke rij uniek zou kunnen identificeren, zou je dit niet lezen .)
Voorbeeld:
CREATE TABLE ##_dupes (col1 int, col2 int, col3 varchar(50));
INSERT INTO ##_dupes
VALUES (1, 1, 'one,one')
, (2, 2, 'two,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, 'one,two')
, (3, 3, 'three,three')
, (1, 1, 'one,one')
, (1, 2, '1,2');
Van de 8 rijen zijn er 5 betrokken bij dubbele problemen; 3 rijen moeten worden verwijderd. Je kunt de problemen hiermee zien:
SELECT col1
, col2
, col3
, COUNT(1) AS _total
FROM ##_dupes
WHERE 1=1
GROUP BY col1, col2, col3
HAVING COUNT(1) > 1
ORDER BY _total DESC;
Voer nu de volgende query uit om de duplicaten te verwijderen, waarbij u 1 rij overhoudt van elke set duplicaten.
WITH numbered AS (
SELECT ROW_NUMBER() OVER(PARTITION BY col1, col2, col3 ORDER BY col1, col2, col3) AS _dupe_num FROM ##_dupes WHERE 1=1
)
DELETE FROM numbered WHERE _dupe_num > 1;
U houdt nu 5 rijen over, waarvan geen enkele is gedupliceerd.