Aký je najlepší spôsob odstránenia duplicitných riadkov z pomerne veľkej tabuľky SQL Servera
(t. j. viac ako 300 000 riadkov)?
Riadky samozrejme nebudú dokonalé duplikáty, pretože existuje identifikačné pole RowID
.
MyTable
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
Za predpokladu, že nie sú žiadne nuly, môžete ZHROMAŽĎOVAŤ podľa
jedinečných stĺpcov a VYBRAŤ
MIN (alebo MAX)
RowId ako riadok, ktorý sa má zachovať. Potom jednoducho odstráňte všetko, čo nemalo id riadku:
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
V prípade, že máte namiesto celého čísla GUID, môžete nahradiť
MIN(RowId)
pomocou
CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
Na stránke podpory spoločnosti Microsoft nájdete dobrý článok o odstraňovaní duplikátov. Je dosť konzervatívny - všetko máte robiť v samostatných krokoch - ale mal by dobre fungovať proti veľkým tabuľkám.
V minulosti som na to používal self-joins, hoci by sa to pravdepodobne dalo vylepšiť klauzulou HAVING:
DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField
AND dupes.secondDupField = fullTable.secondDupField
AND dupes.uniqueField > fullTable.uniqueField
Tu je ďalší dobrý článok o odstraňovaní duplikátov.
Rozoberá, prečo je to ťažké: "SQL je založená na relačnej algebre a duplikáty sa v relačnej algebre nemôžu vyskytovať, pretože duplikáty nie sú v množine povolené."
Riešenie dočasnej tabuľky a dva príklady mysql.
V budúcnosti sa tomu chystáte zabrániť na úrovni databázy, alebo z pohľadu aplikácie. Navrhoval by som databázovú úroveň, pretože vaša databáza by mala byť zodpovedná za udržiavanie referenčnej integrity, vývojári len spôsobia problémy ;)