Nedenfor er seks eksempler, der sletter dublerede rækker fra en tabel i SQLite, når disse rækker har en primær nøgle eller en unik identifikatorkolonne.
I disse tilfælde skal den primære nøgle ignoreres, når dubletter sammenlignes (på grund af det faktum, at primærnøgler pr. definition forhindrer duplikerede rækker).
Eksempeldata
Vores eksempler bruger følgende data:
SELECT * FROM Dogs;
Resultat:
DogId Fornavn Efternavn----- ---------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag JohnsonVi kan se, at de første to rækker indeholder dubletter, ligesom de sidste tre rækker.
DogId
kolonne indeholder unikke værdier (fordi det er tabellens primære nøgle), og derfor er der strengt taget ingen dubletter. Men i virkelige situationer vil du ofte ønske at de-dupere tabeller, der indeholder primærnøgler. Derfor ignorerer vi i de følgende eksempler den primære nøgle og sletter rækker, der indeholder duplikerede værdier på tværs af de resterende kolonner.Valgmulighed 1
Her er vores første mulighed for at de-dupere ovenstående tabel:
DELETE FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName ); SELECT * FROM Dogs;
Resultat:
DogId FirstName Efternavn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonTabellen er blevet de-duperet som forventet.
Vi kan alternativt bruge
MAX()
funktion i stedet forMIN()
funktion til at ændre, hvilke rækker der slettes. Det vil jeg gøre i det næste eksempel.Valgmulighed 2
I dette eksempel (og de følgende eksempler) antager vi, at tabellen er blevet gendannet til sin oprindelige tilstand (med dubletterne).
Her er en anden forespørgsel, der sletter dublerede rækker og vælger de resterende rækker:
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;
Resultat:
DogId FirstName Efternavn----- ---------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag JohnsonTabellen er nu blevet de-duperet.
Bemærk, at jeg brugte
MAX()
funktion i stedet forMIN()
som jeg brugte i det forrige eksempel. Vi kan se, hvilken indflydelse dette har på de-duping-operationen. Den slettede forskellige rækker fra tabellen.Valgmulighed 3
Her er en mulighed, der ikke kræver brug af
MIN()
ellerMAX()
: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;
Resultat:
DogId FirstName Efternavn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonValgmulighed 4
Her er en anden mulighed:
DELETE FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Resultat:
DogId FirstName Efternavn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonValgmulighed 5
Som standard har hver række i SQLite en speciel kolonne, normalt kaldet
rowid
, der entydigt identificerer den pågældende række i tabellen. Medmindre det eksplicit er blevet fjernet fra tabellen, kan du bruge dette som en unik identifikator for hver række. Denne metode kan være nyttig, hvis du af en eller anden grund ikke er i stand til at referere til den primære nøgle (eller hvis tabellen ikke har en primær nøgle).Vi kan derfor bruge
rowid
i vores forespørgsel i stedet forDogId
kolonne: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;
Resultat:
DogId FirstName Efternavn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonValgmulighed 6
Og her er det andet eksempel, men med
rowid
i stedet for den primære nøgle:DELETE FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Resultat:
DogId FirstName Efternavn----- ---------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson