Hier sind elf Optionen zum Zurückgeben doppelter Zeilen in SQLite, wenn diese Zeilen einen Primärschlüssel oder eine andere eindeutige Bezeichnerspalte haben (aber Sie den Primärschlüssel ignorieren möchten).
Das bedeutet, dass die doppelten Zeilen in allen Spalten genau die gleichen Werte aufweisen, mit Ausnahme ihrer Primärschlüssel-/eindeutigen ID-Spalte.
Beispieldaten
Wir verwenden die folgenden Daten für unsere Beispiele:
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 JohnsonDie ersten beiden Zeilen sind Duplikate (mit Ausnahme der
DogId
Spalte, die der Primärschlüssel der Tabelle ist und einen eindeutigen Wert für alle Zeilen enthält). Die letzten drei Zeilen sind ebenfalls Duplikate (mit Ausnahme derDogId
Spalte).Die Primärschlüsselspalte stellt sicher, dass es keine doppelten Zeilen gibt, was sich in RDBMS bewährt hat, da Primärschlüssel dabei helfen, die Datenintegrität durchzusetzen. Da Primärschlüssel jedoch doppelte Zeilen verhindern, können sie unsere Fähigkeit beeinträchtigen, Duplikate zu finden.
In unserer obigen Tabelle ist die Primärschlüsselspalte eine aufsteigende Zahl, und ihr Wert hat keine Bedeutung und ist nicht signifikant. Wir müssen diese Zeile daher ignorieren, wenn wir Duplikate in den anderen Spalten finden wollen.
Möglichkeit 1
Wir können eine Abfrage mit dem
GROUP BY
ausführen -Klausel, um die Spalten nach ihren signifikanten Spalten zu gruppieren, verwenden Sie dannCOUNT()
Funktion, um die Anzahl identischer Zeilen zurückzugeben:SELECT FirstName, LastName, COUNT(*) AS Count FROM Dogs GROUP BY FirstName, LastName ORDER BY Count DESC;
Ergebnis:
Vorname Nachname Anzahl --------- -------- -----Wag Johnson 3 Bark Smith 2 Ruff Robinson 1 Woof Jones 1Hier haben wir die Primärschlüsselspalte ausgeschlossen, indem wir sie aus unserer Abfrage weggelassen haben. Wir haben es auch nach Anzahl in absteigender Reihenfolge sortiert, sodass die Duplikate zuerst angezeigt werden.
Das Ergebnis sagt uns, dass es drei Zeilen mit Wag Johnson und zwei Zeilen mit Bark Smith gibt. Dies sind Duplikate (oder Triplikate im Fall von Wag Johnson). Die anderen beiden Zeilen haben keine Duplikate.
Option 2
Wir können den
HAVING
verwenden -Klausel, um Nicht-Duplikate von der Ausgabe auszuschließen:SELECT FirstName, LastName, COUNT(*) AS Count FROM Dogs GROUP BY FirstName, LastName HAVING COUNT(*) > 1 ORDER BY Count DESC;
Ergebnis:
Vorname Nachname Anzahl --------- -------- -----Wag Johnson 3 Bark Smith 2Möglichkeit 3
Hier ist ein Beispiel für die Suche nach Duplikaten in verketteten Spalten. In diesem Fall verwenden wir den
DISTINCT
Schlüsselwort, um unterschiedliche Werte zu erhalten, und verwenden Sie dannCOUNT()
Funktion, um die Zählung zurückzugeben:SELECT DISTINCT FirstName || ' ' || LastName AS DogName, COUNT(*) AS Count FROM Dogs GROUP BY FirstName || ' ' || LastName ORDER BY Count DESC;
Ergebnis:
DogName Count------------- -----Wag Johnson 3 Bark Smith 2 Woof Jones 1 Ruff Robinson 1Option 4
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.Wir können daher die
rowid
verwenden in unserer Abfrage:SELECT * FROM Dogs WHERE EXISTS ( SELECT 1 FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName AND Dogs.rowid > d2.rowid );
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag JohnsonWir könnten
SELECT *
ersetzen mitDELETE
um eine Deduplizierungsoperation auf der Tabelle durchzuführen.Beachten Sie, dass wir die
DogId
hätten verwenden können Spalte (unser Primärschlüssel) anstelle derrowid
wenn wir wollten. Das heißt, dierowid
kann nützlich sein, wenn Sie die Primärschlüsselspalte aus irgendeinem Grund nicht verwenden können oder wenn die Tabelle keinen Primärschlüssel hat.Option 5
Hier ist eine weitere Abfrage, die die
rowid
verwendet :SELECT * FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName );
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag JohnsonWie im vorherigen Beispiel könnten wir den
SELECT *
ersetzen mitDELETE
um die doppelten Zeilen zu löschen.Option 6
Die beiden
rowid
Die obigen Optionen sind großartig, wenn Sie den Primärschlüssel in Ihrer Abfrage vollständig ignorieren müssen (oder wenn Sie überhaupt keine Primärschlüsselspalte haben). Wie bereits erwähnt, besteht jedoch immer noch die Möglichkeit,rowid
zu ersetzen mit der Primärschlüsselspalte – in unserem Fall dieDogId
Spalte:SELECT * FROM Dogs WHERE EXISTS ( SELECT 1 FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName AND Dogs.DogId > d2.DogId );
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOption 7
Und hier ist die andere Abfrage mit der
rowid
durch dieDogId
ersetzt Spalte:SELECT * FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName );
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOption 8
Eine andere Möglichkeit ist die Verwendung von
ROW_NUMBER()
Fensterfunktion:SELECT *, ROW_NUMBER() OVER ( PARTITION BY FirstName, LastName ORDER BY FirstName, LastName ) AS Row_Number FROM Dogs;
Ergebnis:
DogId FirstName LastName Row_Number----- --------- -------- ----------1 Bark Smith 1 2 Bark Smith 2 4 Ruff Robinson 1 5 Wag Johnson 1 6 Wag Johnson 2 7 Wag Johnson 3 3 Woof Jones 1Verwenden der
PARTITION
-Klausel führt dazu, dass eine neue Spalte hinzugefügt wird, mit einer Zeilennummer, die sich jedes Mal erhöht, wenn es ein Duplikat gibt, aber wieder zurückgesetzt wird, wenn es eine eindeutige Zeile gibt.In diesem Fall gruppieren wir die Ergebnisse nicht, was bedeutet, dass wir jede doppelte Zeile sehen können, einschließlich ihrer eindeutigen ID-Spalte.
Option 9
Wir können das vorherige Beispiel auch als allgemeinen Tabellenausdruck in einer größeren Abfrage verwenden:
WITH cte AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY FirstName, LastName ORDER BY FirstName, LastName ) AS Row_Number FROM Dogs ) SELECT * FROM cte WHERE Row_Number <> 1;
Ergebnis:
DogId FirstName LastName Row_Number----- --------- -------- ----------2 Bark Smith 2 6 Wag Johnson 2 7 Wag Johnson 3Dadurch werden Nicht-Duplikate aus der Ausgabe ausgeschlossen, und es wird eine Zeile jedes Duplikats aus der Ausgabe ausgeschlossen.
Option 10
Hier ist eine andere Möglichkeit, dieselbe Ausgabe wie im vorherigen Beispiel zu erhalten:
SELECT * FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName );
Ergebnis:
HundId Vorname Nachname ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag JohnsonOption 11
Hier ist noch eine weitere Option, um Duplikate aus unserer Tabelle auszuwählen:
SELECT * 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 );
Ergebnis:
DogId Vorname Nachname DogId Vorname Nachname----- --------- -------- ----- --------- ----- ---2 Bark Smith 1 Bark Smith 7 Wag Johnson 5 Wag Johnson 7 Wag Johnson 6 Wag Johnson