SQLite
 sql >> Datenbank >  >> RDS >> SQLite

6 Möglichkeiten zum Auswählen doppelter Zeilen in SQLite

Die folgenden Abfragen können verwendet werden, um doppelte Zeilen in SQLite zurückzugeben.

Hier enthalten die doppelten Zeilen doppelte Werte in allen Spalten, einschließlich der ID-Spalte.

Beispieldaten

Angenommen, wir haben eine Tabelle mit den folgenden Daten:

SELECT * FROM Pets; 

Ergebnis:

PetId PetName PetType----- ------- ------- 1 Wag Dog 1 Wag Dog 2 Scratch Cat 3 Tweet Bird 4 Bell Dog 4 Bell Dog 4 Bell Dog 

Die ersten beiden Zeilen sind Duplikate, ebenso wie die letzten drei Zeilen. Das liegt daran, dass alle drei Spalten in jeder doppelten Zeile dieselben Werte enthalten.

Option 1

Wir können die folgende Abfrage verwenden, um zu sehen, wie viele Zeilen Duplikate sind:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId; 

Ergebnis:

PetId PetName PetType Count----- ------- ------- ----- 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bell Dog 3 

Hier haben wir die Zeilen nach allen Spalten gruppiert und die Zeilenanzahl jeder Gruppe zurückgegeben. Dies sagt uns, ob eine Zeile eindeutig (mit einer Anzahl von 1) oder ein Duplikat (mit einer Anzahl größer als 1) ist.

Wir können es nach Anzahl in absteigender Reihenfolge sortieren, sodass die Zeilen mit den meisten Duplikaten zuerst erscheinen:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC; 

Ergebnis:

PetId PetName PetType Count----- ------- ------- -----4 Hund bellen 3 1 Hund wedeln 2 2 Katze kratzen 1 3 Vogel twittern 1 

Option 2

Wenn nur die doppelten Zeilen aufgelistet werden sollen, können wir den HAVING verwenden -Klausel, um nur Zeilen mit einer Anzahl größer als 1 zurückzugeben:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId; 

Ergebnis:

PetId PetName PetType Count----- ------- ------- -----1 Wedelnder Hund 2 4 Bellender Hund 3 

Option 3

Eine weitere Option ist die Verwendung von ROW_NUMBER() Fensterfunktion:

SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets; 

Ergebnis:

PetId PetName PetType Row_Number----- ------- ------- ----------1 Wag Dog 1 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Vogel 1 4 Bellen Hund 1 4 Bellen Hund 2 4 Bellen Hund 3 

Die PARTITION BY -Klausel teilt die von FROM erzeugte Ergebnismenge -Klausel in Partitionen, auf die die Funktion angewendet wird. Wenn wir Partitionen für die Ergebnismenge angeben, bewirkt jede Partition, dass die Nummerierung erneut beginnt (d. h. die Nummerierung beginnt bei 1 für die erste Zeile in jeder Partition).

Option 4

Wir können die obige Abfrage als allgemeinen Tabellenausdruck verwenden:

WITH cte AS 
    (
        SELECT 
            *, 
            ROW_NUMBER() OVER ( 
                PARTITION BY PetId, PetName, PetType 
                ORDER BY PetId, PetName, PetType
                ) AS Row_Number
        FROM Pets
    )
SELECT * FROM cte WHERE Row_Number <> 1; 

Ergebnis:

PetId PetName PetType Row_Number----- ------- ------- ----------1 Hund wedeln 2 4 Hund bellen 2 4 Hund bellen 3  

Dadurch werden nur die überschüssigen Zeilen aus den übereinstimmenden Duplikaten zurückgegeben. Wenn also zwei identische Zeilen vorhanden sind, wird eine davon zurückgegeben. Wenn es drei identische Zeilen gibt, werden zwei zurückgegeben und so weiter.

Diese Abfrage kann nützlich sein, um anzuzeigen, wie viele Zeilen bei einem Deduplizierungsvorgang aus der Tabelle entfernt werden. In einigen anderen DBMSs (zumindest in SQL Server) können wir das letzte SELECT * ersetzen mit DELETE um die doppelten Zeilen aus der Tabelle zu löschen. Aber SQLite lässt uns den CTE nicht so aktualisieren.

Glücklicherweise können die nächsten beiden Optionen geändert werden, um einen Löschvorgang durchzuführen.

Option 5

Wir können die rowid von SQLite nutzen :

SELECT * FROM Pets
WHERE EXISTS (
  SELECT 1 FROM Pets p2 
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
  AND Pets.rowid > p2.rowid
); 

Ergebnis:

PetId PetName PetType----- ------- -------1 Wackelnder Hund 4 bellender Hund 4 bellender Hund 

Wie funktioniert das? Standardmäßig hat jede Zeile in SQLite eine spezielle Spalte, die normalerweise als rowid bezeichnet wird , die diese Zeile innerhalb der Tabelle eindeutig identifiziert. Dies kann bei Bedarf entfernt werden, aber wenn es nicht ausdrücklich entfernt wurde, können Sie es in Ihren Abfragen nutzen.

Option 6

Und schließlich hier eine weitere Option, die die rowid von SQLite verwendet :

SELECT * FROM Pets
WHERE rowid > (
  SELECT MIN(rowid) FROM Pets p2  
  WHERE Pets.PetName = p2.PetName
  AND Pets.PetType = p2.PetType
); 

Ergebnis:

PetId PetName PetType----- ------- -------1 Wackelnder Hund 4 bellender Hund 4 bellender Hund