Kakšen je najboljši način za odstranitev podvojenih vrstic iz precej velike tabele SQL Server
(tj. več kot 300.000 vrstic)?
Vrstice seveda ne bodo popolnoma podvojene zaradi obstoja identifikacijskega polja RowID
.
Moja tabela
RowID int not null identity(1,1) primary key,
Col1 varchar(20) not null,
Col2 varchar(2048) not null,
Col3 tinyint not null
Če ni ničelnih številk, skupini po
edinstvenih stolpcih in izberi
najmanjši (ali največji) vrsticni indeks kot vrstico, ki jo boš ohranil. Nato izbrišete vse, ki nimajo id vrstice:
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
Če imate namesto celega števila GUID, lahko zamenjate
MIN(RowId)
s
CONVERT(uniqueidentifier, MIN(CONVERT(char(36), MyGuidColumn)))
Na spletnem mestu Microsoftove podpore je dober članek o odstranjevanju dvojnikov. Je precej konzervativen - vse morate narediti v ločenih korakih - vendar bi moral dobro delovati pri velikih tabelah.
V preteklosti sem za to uporabljal samospajanje, čeprav bi ga verjetno lahko izboljšali s klavzulo HAVING:
DELETE dupes
FROM MyTable dupes, MyTable fullTable
WHERE dupes.dupField = fullTable.dupField
AND dupes.secondDupField = fullTable.secondDupField
AND dupes.uniqueField > fullTable.uniqueField
Tukaj je še en dober članek o odstranjevanju dvojnikov.
V njem je opisano, zakaj je to težko: "SQL temelji na relacijski algebri, v relacijski algebri pa se podvojitve ne morejo pojaviti, ker podvojitve niso dovoljene v množici."
Rešitev za začasno tabelo in dva primera mysql.
Ali boste v prihodnosti to preprečevali na ravni podatkovne zbirke ali z vidika aplikacije. Predlagam raven podatkovne zbirke, saj bi morala biti vaša podatkovna zbirka odgovorna za vzdrževanje referenčne celovitosti, razvijalci pa bodo le povzročali težave ;)