Níže je šest příkladů, které odstraní duplicitní řádky z tabulky v SQLite, když tyto řádky mají sloupec primárního klíče nebo jedinečného identifikátoru.
V těchto případech musí být primární klíč při porovnávání duplikátů ignorován (vzhledem k tomu, že primární klíče podle definice zabraňují duplicitním řádkům).
Ukázková data
Naše příklady používají následující data:
SELECT * FROM Dogs;
Výsledek:
DogId Jméno Příjmení----- --------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag JohnsonVidíme, že první dva řádky obsahují duplikáty, stejně jako poslední tři řádky.
DogId
sloupec obsahuje jedinečné hodnoty (protože je to primární klíč tabulky), a proto, přísně vzato, neexistují žádné duplikáty. Ale v reálných situacích budete často chtít odstranit duplicitní tabulky, které obsahují primární klíče. Proto v následujících příkladech ignorujeme primární klíč a odstraníme řádky, které obsahují duplicitní hodnoty ve zbývajících sloupcích.Možnost 1
Zde je naše první možnost, jak odstranit duplikáty výše uvedené tabulky:
DELETE FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonTabulka byla odstraněna podle očekávání.
Alternativně můžeme použít
MAX()
místo funkceMIN()
funkce pro změnu, které řádky se mají smazat. Udělám to v dalším příkladu.Možnost 2
V tomto příkladu (a v následujících příkladech) budeme předpokládat, že tabulka byla obnovena do původního stavu (s duplikáty).
Zde je další dotaz, který odstraní duplicitní řádky a vybere zbývající řádky:
DELETE FROM Dogs WHERE DogId IN ( SELECT d2.DogId FROM Dogs d1, Dogs d2 WHERE d1.FirstName = d2.FirstName AND d1.LastName = d2.LastName AND d1.DogId <> d2.DogId AND d1.DogId=( SELECT MAX(DogId) FROM Dogs d3 WHERE d3.FirstName = d1.FirstName AND d3.LastName = d1.LastName ) ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag JohnsonTabulka byla nyní deduplikována.
Všimněte si, že jsem použil
MAX()
funkce namístoMIN()
který jsem použil v předchozím příkladu. Vidíme, jaký to má vliv na operaci odstranění duplikace. Z tabulky byly odstraněny různé řádky.Možnost 3
Zde je možnost, která nevyžaduje použití
MIN()
neboMAX()
:DELETE FROM Dogs WHERE EXISTS ( SELECT 1 FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName AND Dogs.DogId > d2.DogId ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonMožnost 4
Zde je další možnost:
DELETE FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonMožnost 5
Ve výchozím nastavení má každý řádek v SQLite speciální sloupec, obvykle nazývaný
rowid
, který jednoznačně identifikuje daný řádek v tabulce. Pokud nebyl explicitně odstraněn z tabulky, můžete jej použít jako jedinečný identifikátor pro každý řádek. Tato metoda může být užitečná, pokud z nějakého důvodu nemůžete odkazovat na primární klíč (nebo pokud tabulka primární klíč nemá).Můžeme tedy použít
rowid
v našem dotazu namístoDogId
sloupec:DELETE FROM Dogs WHERE EXISTS ( SELECT 1 FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName AND Dogs.rowid > d2.rowid ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonMožnost 6
A zde je další příklad, ale s
rowid
místo primárního klíče:DELETE FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Výsledek:
DogId FirstName Příjmení----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson