MariaDB
 sql >> Database >  >> RDS >> MariaDB

4 modi per selezionare righe duplicate in MariaDB

Se hai una tabella che sospetti abbia righe duplicate nel tuo database MariaDB, puoi utilizzare una delle seguenti query per avere un'idea di quante righe sono duplicate.

Dati di esempio

Supponiamo di avere una tabella con i seguenti dati:

SELECT * FROM Pets;

Risultato:

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

Le prime due righe sono duplicate e le ultime tre righe sono duplicate.

Opzione 1

Possiamo usare la seguente query per vedere quante righe sono duplicate:

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

Risultato:

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

Possiamo espandere il SELECT elenco per includere più colonne se necessario:

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

Risultato:

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

Possiamo in alternativa ordinarlo per conteggio in ordine decrescente, in modo che le righe con il maggior numero di duplicati appaiano per prime:

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

Risultato:

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

Opzione 2

Se vogliamo che vengano elencate solo le righe duplicate, possiamo usare the HAVING clausola per escludere righe non duplicate:

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

Risultato:

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

Opzione 3

Un altro modo per farlo è usare ROW_NUMBER() funzione con il PARTITION BY clausola per numerare l'output del set di risultati.

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

Risultato:

+-------+---------+---------+------------+
| PetId | PetName | PetType | Row_Number |
+-------+---------+---------+------------+
|     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 |
+-------+---------+---------+------------+

Il PARTITION BY La clausola divide il set di risultati prodotto dal FROM clausola in partizioni a cui viene applicata la funzione. Quando specifichiamo le partizioni per il set di risultati, ogni partizione fa ricominciare la numerazione (cioè la numerazione inizierà da 1 per la prima riga in ogni partizione).

Opzione 4

Per restituire solo le righe in eccesso dai duplicati corrispondenti, possiamo utilizzare la query precedente come un'espressione di tabella comune, come questa:

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;

Risultato:

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