Hieronder staan zes voorbeelden die dubbele rijen verwijderen uit een tabel in SQLite wanneer die rijen een primaire sleutel of een unieke id-kolom hebben.
In deze gevallen moet de primaire sleutel worden genegeerd bij het vergelijken van duplicaten (omdat primaire sleutels per definitie dubbele rijen voorkomen).
Voorbeeldgegevens
Onze voorbeelden gebruiken de volgende gegevens:
SELECT * FROM Dogs;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson 6 Wag Johnson 7 Wag Johnson
We kunnen zien dat de eerste twee rijen duplicaten bevatten, net als de laatste drie rijen.
De DogId
kolom bevat unieke waarden (omdat het de primaire sleutel van de tabel is) en daarom zijn er strikt genomen geen duplicaten. Maar in de praktijk wil je vaak tabellen met primaire sleutels ontdubbelen. Daarom negeren we in de volgende voorbeelden de primaire sleutel en verwijderen we rijen die dubbele waarden bevatten in de overige kolommen.
Optie 1
Dit is onze eerste optie om de bovenstaande tabel te ontdubbelen:
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
SELECT * FROM Dogs;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
De tafel is zoals verwacht ontdubbeld.
We kunnen ook de MAX()
. gebruiken functie in plaats van de MIN()
functie om te wijzigen welke rijen worden verwijderd. Ik doe dit in het volgende voorbeeld.
Optie 2
In dit voorbeeld (en de volgende voorbeelden) gaan we ervan uit dat de tabel in de oorspronkelijke staat is hersteld (met de duplicaten).
Hier is nog een zoekopdracht die dubbele rijen verwijdert en de resterende rijen selecteert:
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;
Resultaat:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 7 Wag Johnson
De tafel is nu ontdubbeld.
Merk op dat ik de MAX()
. heb gebruikt functie in plaats van MIN()
die ik in het vorige voorbeeld heb gebruikt. We kunnen zien welk effect dit heeft op de ontdubbelingsoperatie. Het heeft verschillende rijen uit de tabel verwijderd.
Optie 3
Hier is een optie die het gebruik van MIN()
. niet vereist of MAX()
:
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;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Optie 4
Hier is nog een optie:
DELETE FROM Dogs
WHERE DogId > (
SELECT MIN(DogId) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Optie 5
Standaard heeft elke rij in SQLite een speciale kolom, meestal de rowid
, die die rij in de tabel op unieke wijze identificeert. Tenzij het expliciet uit de tabel is verwijderd, kunt u dit gebruiken als een unieke id voor elke rij. Deze methode kan handig zijn als u om de een of andere reden niet naar de primaire sleutel kunt verwijzen (of als de tabel geen primaire sleutel heeft).
We kunnen daarom de rowid
. gebruiken in onze zoekopdracht in plaats van de DogId
kolom:
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;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Optie 6
En hier is het andere voorbeeld, maar met rowid
in plaats van de primaire sleutel:
DELETE FROM Dogs
WHERE rowid > (
SELECT MIN(rowid) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Resultaat:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson