Kako lahko odstranim podvojene vrstice?

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
Rešitev

Č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)))
Komentarji (30)

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
Komentarji (0)

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 ;)

Komentarji (1)