Hoe kan ik dubbele rijen verwijderen?

Wat is de beste manier om dubbele rijen te verwijderen uit een vrij grote SQL Server tabel (d.w.z. 300.000+ rijen)?

De rijen zullen natuurlijk geen perfecte duplicaten zijn vanwege het bestaan van het RowID identiteitsveld.

MijnTabel

RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
Oplossing

Ervan uitgaande dat er geen nullen zijn, je GROUP BY de unieke kolommen, en SELECT de MIN (of MAX) RowId als de te behouden rij. Dan, verwijder alles dat geen rij id heeft:

DELETE FROM MyTable
LEFT OUTER JOIN (
   SELECT MIN(RowId) as RowId, Col1, Col2, Col3 
   FROM MyTable 
   GROUP BY Col1, Col2, Col3
) as KeepRows ON
   MyTable.RowId = KeepRows.RowId
WHERE
   KeepRows.RowId IS NULL

In het geval dat je een GUID hebt in plaats van een integer, kun je

MIN(RowId)

door

CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
Commentaren (30)

Er'is een goed artikel over verwijderen van duplicaten op de Microsoft Support site. Het'is vrij conservatief - ze laten je alles in afzonderlijke stappen doen - maar het zou goed moeten werken tegen grote tabellen.

Ik'heb self-joins gebruikt om dit in het verleden te doen, hoewel het waarschijnlijk kan worden opgeknapt met een HAVING-clausule:

DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField 
AND dupes.secondDupField = fullTable.secondDupField 
AND dupes.uniqueField > fullTable.uniqueField
Commentaren (0)

Hier is nog een goed artikel over het verwijderen van duplicaten.

Het bespreekt waarom het moeilijk is: "SQL is gebaseerd op relationele algebra, en duplicaten kunnen niet voorkomen in relationele algebra, omdat duplicaten niet zijn toegestaan in een set."

De temp table oplossing, en twee mysql voorbeelden.

In de toekomst, ga je het voorkomen op database niveau, of vanuit een applicatie perspectief. Ik zou het databaseniveau voorstellen, omdat je database verantwoordelijk zou moeten zijn voor het handhaven van referentiële integriteit, ontwikkelaars zullen alleen maar problemen veroorzaken ;)

Commentaren (1)