Mysql
 sql >> Datenbank >  >> RDS >> Mysql

4 Möglichkeiten, doppelte Zeilen in MySQL zu finden

Wenn Sie glauben, dass eine MySQL-Tabelle möglicherweise doppelte Zeilen enthält, können Sie die folgenden Optionen verwenden, um alle Duplikate zurückzugeben.

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. Die doppelten Zeilen haben dieselben Werte in allen Spalten.

Option 1

Eine Möglichkeit besteht darin, die folgende Abfrage zu verwenden, um doppelte Zeilen zurückzugeben:

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

Ergebnis:

+-------+-------+
| PetId | Count |
+-------+-------+
|     1 |     2 |
|     2 |     1 |
|     3 |     1 |
|     4 |     3 |
+-------+-------+

Wir können SELECT erweitern Liste, um bei Bedarf weitere Spalten aufzunehmen:

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 können die Duplikate zuerst erscheinen lassen, indem wir sie nach Anzahl in absteigender Reihenfolge ordnen:

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 wir nur die doppelten Zeilen auflisten wollen, können wir den HAVING verwenden -Klausel, um Nicht-Duplikate von der Ausgabe auszuschließen:

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 | Wag     | Dog     |     2 |
|     4 | Bark    | Dog     |     3 |
+-------+---------+---------+-------+

Option 3

Eine andere Möglichkeit ist die Verwendung von ROW_NUMBER() Funktion mit dem PARTITION BY -Klausel, um die Ausgabe der Ergebnismenge zu nummerieren.

SELECT 
    *, 
    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 wieder von vorne beginnt (d. h. die Nummerierung beginnt bei 1 für die erste Zeile in jeder Partition).

Option 4

Um nur die überschüssigen Zeilen aus den übereinstimmenden Duplikaten zurückzugeben, können wir die obige Abfrage wie folgt als allgemeinen Tabellenausdruck verwenden:

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

Ergebnis:

+-------+---------+---------+----+
| PetId | PetName | PetType | rn |
+-------+---------+---------+----+
|     1 | Wag     | Dog     |  2 |
|     4 | Bark    | Dog     |  2 |
|     4 | Bark    | Dog     |  3 |
+-------+---------+---------+----+