sql >> Databasteknik >  >> RDS >> Mysql

4 sätt att hitta dubbletter av rader i MySQL

Om du tror att en MySQL-tabell kan ha dubbletter av rader kan du använda följande alternativ för att returnera alla dubbletter.

Exempeldata

Anta att vi har en tabell med följande data:

SELECT * FROM Pets;

Resultat:

+-------+---------+---------+
| PetId | PetName | PetType |
+-------+---------+---------+
|     1 | Wag     | Dog     |
|     1 | Wag     | Dog     |
|     2 | Scratch | Cat     |
|     3 | Tweet   | Bird    |
|     4 | Bark    | Dog     |
|     4 | Bark    | Dog     |
|     4 | Bark    | Dog     |
+-------+---------+---------+

De två första raderna är dubbletter, liksom de tre sista raderna. Dubblettraderna delar samma värden i alla kolumner.

Alternativ 1

Ett alternativ är att använda följande fråga för att returnera dubbletter av rader:

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

Resultat:

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

Vi kan utöka SELECT lista för att inkludera fler kolumner om det behövs:

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

Resultat:

+-------+---------+---------+-------+
| PetId | PetName | PetType | Count |
+-------+---------+---------+-------+
|     1 | Wag     | Dog     |     2 |
|     2 | Scratch | Cat     |     1 |
|     3 | Tweet   | Bird    |     1 |
|     4 | Bark    | Dog     |     3 |
+-------+---------+---------+-------+

Vi kan få dubbletterna att visas först genom att beställa dem efter antal i fallande ordning:

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

Resultat:

+-------+---------+---------+-------+
| PetId | PetName | PetType | Count |
+-------+---------+---------+-------+
|     4 | Bark    | Dog     |     3 |
|     1 | Wag     | Dog     |     2 |
|     2 | Scratch | Cat     |     1 |
|     3 | Tweet   | Bird    |     1 |
+-------+---------+---------+-------+

Alternativ 2

Om vi ​​bara vill lista dubblettraderna kan vi använda koden HAVING sats för att utesluta icke-dubbel från utdata:

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

Resultat:

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

Alternativ 3

Ett annat sätt att göra det är att använda ROW_NUMBER() funktion med PARTITION BY sats för att numrera resultatet av resultatuppsättningen.

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

Resultat:

+-------+---------+---------+----+
| 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 |
+-------+---------+---------+----+

PARTITION BY satsen delar resultatuppsättningen som produceras av FROM sats i partitioner som funktionen tillämpas på. När vi anger partitioner för resultatuppsättningen, gör varje partition att numreringen börjar om igen (dvs. numreringen börjar på 1 för den första raden i varje partition).

Alternativ 4

För att bara returnera överskottsraderna från matchande dubbletter kan vi använda ovanstående fråga som ett vanligt tabelluttryck, så här:

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;

Resultat:

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

  1. Oracle-fråga för att hämta kolumnnamn

  2. Ett enkelt användningsfall för index på primärnycklar

  3. Frågefel med tvetydigt kolumnnamn i SQL

  4. SQL Server - Auto-inkrementering som tillåter UPDATE-satser