Unten sind sechs Beispiele, die doppelte Zeilen aus einer Tabelle in SQLite löschen, wenn diese Zeilen einen Primärschlüssel oder eine eindeutige Bezeichnerspalte haben.
In diesen Fällen muss der Primärschlüssel beim Vergleich von Duplikaten ignoriert werden (aufgrund der Tatsache, dass Primärschlüssel per Definition doppelte Zeilen verhindern).
Beispieldaten
Unsere Beispiele verwenden die folgenden Daten:
SELECT * FROM Dogs;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag JohnsonWir können sehen, dass die ersten beiden Zeilen Duplikate enthalten, ebenso wie die letzten drei Zeilen.
Die
DogId
Spalte enthält eindeutige Werte (weil es der Primärschlüssel der Tabelle ist), und daher gibt es streng genommen keine Duplikate. In realen Situationen möchten Sie jedoch häufig Tabellen deduplizieren, die Primärschlüssel enthalten. Daher ignorieren wir in den folgenden Beispielen den Primärschlüssel und löschen Zeilen, die doppelte Werte in den verbleibenden Spalten enthalten.Option 1
Hier ist unsere erste Option zum Deduplizieren der obigen Tabelle:
DELETE FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName ); SELECT * FROM Dogs;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonDie Tabelle wurde wie erwartet dedupliziert.
Wir können alternativ den
MAX()
verwenden anstelle vonMIN()
Funktion, um zu ändern, welche Zeilen gelöscht werden. Ich werde dies im nächsten Beispiel tun.Option 2
In diesem Beispiel (und den folgenden Beispielen) gehen wir davon aus, dass die Tabelle in ihrem ursprünglichen Zustand (mit den Duplikaten) wiederhergestellt wurde.
Hier ist eine weitere Abfrage, die doppelte Zeilen löscht und die verbleibenden Zeilen auswählt:
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;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag JohnsonDie Tabelle wurde nun dedupliziert.
Beachten Sie, dass ich
MAX()
verwendet habe Funktion anstelle vonMIN()
die ich im vorherigen Beispiel verwendet habe. Wir können die Auswirkungen sehen, die dies auf den Deduplizierungsvorgang hat. Es hat verschiedene Zeilen aus der Tabelle gelöscht.Option 3
Hier ist eine Option, die keine Verwendung von
MIN()
erfordert oderMAX()
: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;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOption 4
Hier ist eine weitere Option:
DELETE FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOption 5
Standardmäßig hat jede Zeile in SQLite eine spezielle Spalte, die normalerweise als
rowid
bezeichnet wird , die diese Zeile innerhalb der Tabelle eindeutig identifiziert. Sofern es nicht ausdrücklich aus der Tabelle entfernt wurde, können Sie dies als eindeutige Kennung für jede Zeile verwenden. Diese Methode kann nützlich sein, wenn Sie aus irgendeinem Grund nicht auf den Primärschlüssel verweisen können (oder wenn die Tabelle keinen Primärschlüssel hat).Wir können daher die
rowid
verwenden in unserer Abfrage anstelle derDogId
Spalte: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;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOption 6
Und hier ist das andere Beispiel, aber mit
rowid
anstelle des Primärschlüssels:DELETE FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson