Die folgenden Beispiele geben doppelte Zeilen aus einer Oracle-Datenbanktabelle zurück.
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 Bark Dog 4 Bark Dog 4 Bark Dog
Die ersten beiden Zeilen sind Duplikate, ebenso wie die letzten drei Zeilen. In diesem Fall enthalten die doppelten Zeilen doppelte Werte in allen Spalten, einschließlich der ID-Spalte.
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 Bark Dog 3
Wir haben die Zeilen nach allen Spalten gruppiert und die Zeilenanzahl jeder Gruppe zurückgegeben. Jede Zeile mit einer Anzahl größer als 1 ist ein Duplikat.
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 Bark Dog 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 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 COUNT(*) DESC;
Ergebnis:
PETID PETNAME PETTYPE Count 4 Bark Dog 3 1 Wag Dog 2
Option 3
Eine weitere Option ist die Verwendung von ROW_NUMBER()
Fensterfunktion:
SELECT
PetId,
PetName,
PetType,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS rn
FROM Pets;
Ergebnis:
PETID PETNAME PETTYPE RN 1 Wag Dog 1 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bark Dog 1 4 Bark Dog 2 4 Bark Dog 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
PetId,
PetName,
PetType,
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 Wag Dog 2 4 Bark Dog 2 4 Bark Dog 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.
Option 5
Da unsere Tabelle keine Primärschlüsselspalte enthält, können wir Oracles rowid
nutzen Pseudospalte:
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 Wag Dog 4 Bark Dog 4 Bark Dog
Das funktioniert so, dass jede Zeile in einer Oracle-Datenbank eine rowid
hat Pseudospalte, die die Adresse der Zeile zurückgibt. Die rowid
ist ein eindeutiger Bezeichner für Zeilen in der Tabelle, und normalerweise identifiziert sein Wert eine Zeile in der Datenbank eindeutig. Beachten Sie jedoch, dass Zeilen in verschiedenen Tabellen, die zusammen im selben Cluster gespeichert sind, dieselbe rowid
haben können .
Ein Vorteil des obigen Beispiels ist, dass wir SELECT *
ersetzen können mit DELETE
um die Tabelle zu deduplizieren.
Option 6
Und schließlich, hier ist eine weitere Option, die die rowid
verwendet Pseudospalte:
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 Wag Dog 4 Bark Dog 4 Bark Dog
Gleiches Ergebnis wie im vorherigen Beispiel.
Wie im vorherigen Beispiel können wir SELECT *
ersetzen mit DELETE
um doppelte Zeilen aus der Tabelle zu entfernen.