Hier sind sieben Möglichkeiten, doppelte Zeilen in MariaDB zurückzugeben, wenn diese Zeilen einen -Primärschlüssel oder eine andere eindeutige Kennungsspalte haben.
Daher haben die doppelten Zeilen in allen Spalten genau die gleichen Werte, mit Ausnahme ihrer eindeutigen ID-Spalte.
Beispieldaten
Wir verwenden die folgenden Daten für unsere Beispiele:
SELECT * FROM Dogs;
Ergebnis:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 2 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +-------+-----------+----------+
Die 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 der DogId
Spalte).
Die Primärschlüsselspalte stellt sicher, dass es keine doppelten Zeilen gibt, was normalerweise in RDBMSs eine gute Sache ist. Per Definition bedeutet dies jedoch, dass es keine Duplikate gibt. In unserem Fall ist die Primärschlüsselspalte eine aufsteigende Zahl, und ihr Wert hat keine Bedeutung und ist nicht signifikant. Daher müssen wir diese Zeile ignorieren, wenn wir Duplikate in den vorhandenen Spalten finden wollen von Bedeutung.
Möglichkeit 1
Wir können den GROUP BY
verwenden -Klausel, um die Spalten nach ihren signifikanten Spalten zu gruppieren, und verwenden Sie dann den COUNT()
Funktion, um die Anzahl identischer Zeilen zurückzugeben:
SELECT
FirstName,
LastName,
COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName;
Ergebnis:
+-----------+----------+-------+ | FirstName | LastName | Count | +-----------+----------+-------+ | Bark | Smith | 2 | | Ruff | Robinson | 1 | | Wag | Johnson | 3 | | Woof | Jones | 1 | +-----------+----------+-------+
Wir konnten die Primärschlüsselspalte ausschließen, indem wir sie aus unserer Abfrage wegließen.
Das Ergebnis sagt uns, dass es zwei Zeilen mit Bark Smith und drei Zeilen mit Wag Johnson gibt. Dies sind Duplikate (oder Triplikate im Fall von Wag Johnson). Die anderen beiden Zeilen haben keine Duplikate.
Option 2
Mit dem HAVING
können wir Nicht-Duplikate von der Ausgabe ausschließen Klausel:
SELECT
FirstName,
LastName,
COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1;
Ergebnis:
+-----------+----------+-------+ | FirstName | LastName | Count | +-----------+----------+-------+ | Bark | Smith | 2 | | Wag | Johnson | 3 | +-----------+----------+-------+
Möglichkeit 3
Es ist auch möglich, verkettete Spalten auf Duplikate zu prüfen. Zum Beispiel können wir den CONCAT()
verwenden Um unsere beiden Spalten zu verketten, verwenden Sie die Funktion DISTINCT
Schlüsselwort, um unterschiedliche Werte zu erhalten, und verwenden Sie dann COUNT()
Funktion, um die Zählung zurückzugeben:
SELECT
DISTINCT CONCAT(FirstName, ' ', LastName) AS DogName,
COUNT(*) AS Count
FROM Dogs
GROUP BY CONCAT(FirstName, ' ', LastName);
Ergebnis:
+---------------+-------+ | DogName | Count | +---------------+-------+ | Bark Smith | 2 | | Ruff Robinson | 1 | | Wag Johnson | 3 | | Woof Jones | 1 | +---------------+-------+
Option 4
Wir können die ROW_NUMBER()
verwenden Funktion mit dem PARTITION BY
Klausel:
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 | | 6 | Wag | Johnson | 1 | | 5 | Wag | Johnson | 2 | | 7 | Wag | Johnson | 3 | | 3 | Woof | Jones | 1 | +-------+-----------+----------+------------+
Dadurch wird eine neue Spalte mit einer Zeilennummer erstellt, die jedes Mal erhöht wird, wenn ein Duplikat vorhanden ist, aber wieder zurückgesetzt wird, wenn eine eindeutige Zeile vorhanden ist.
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 5
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 | | 5 | Wag | Johnson | 2 | | 7 | Wag | Johnson | 3 | +-------+-----------+----------+------------+
Dadurch werden Nicht-Duplikate aus der Ausgabe ausgeschlossen, und es wird eine Zeile jedes Duplikats aus der Ausgabe ausgeschlossen.
Diese Abfrage könnte als Vorläufer einer Deduplizierungsoperation verwendet werden. Es kann uns zeigen, was gelöscht wird, wenn wir uns entscheiden, Duplikate zu löschen. Um die Tabelle zu deduplizieren, müssen wir lediglich das letzte SELECT *
ersetzen mit DELETE
.
Option 6
Hier ist ein prägnanterer Weg, um die gleiche 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:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 2 | Bark | Smith | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +-------+-----------+----------+
Dieses Beispiel erfordert keine Generierung unserer eigenen separaten Zeilennummer.
Wir können SELECT *
ersetzen mit DELETE
um die Duplikate zu löschen.
Option 7
Und schließlich ist hier eine weitere Option zum Zurückgeben von Duplikaten:
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 | FirstName | LastName | DogId | FirstName | LastName | +-------+-----------+----------+-------+-----------+----------+ | 2 | Bark | Smith | 1 | Bark | Smith | | 7 | Wag | Johnson | 5 | Wag | Johnson | | 7 | Wag | Johnson | 6 | Wag | Johnson | +-------+-----------+----------+-------+-----------+----------+