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

2 modi per eliminare le righe duplicate in MariaDB (ignora la chiave primaria)

Di seguito sono riportati esempi di rimozione di righe duplicate da una tabella in MariaDB quando tali righe hanno una chiave primaria o una colonna identificatore univoco.

Gli esempi eliminano le righe duplicate ma ne conservano una. Quindi, nel caso di due righe identiche, ne cancella una e conserva l'altra.

Dati di esempio

I nostri esempi utilizzano i seguenti dati:

SELECT * FROM Dogs;

Risultato:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     2 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Possiamo vedere che le prime due righe sono duplicate, così come le ultime tre righe.

Il DogId colonna contiene valori univoci (perché è la chiave primaria della tabella) e quindi, in senso stretto, non ci sono duplicati. Ma nelle situazioni della vita reale, spesso vorrai deduplicare le tabelle che contengono chiavi primarie. Pertanto, in questo articolo ignoriamo la chiave primaria e rileviamo valori duplicati nelle colonne rimanenti.

Opzione 1

Iniziamo la nostra prima opzione selezionando tutte le righe che verranno eliminate:

SELECT * FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

Risultato:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     2 | Bark      | Smith    |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Per rimuovere quelle righe duplicate, possiamo cambiare il SELECT * a DELETE :

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

Risultato:

Query OK, 3 rows affected (0.017 sec)

E per verificare il risultato, possiamo selezionare tutte le righe rimanenti nella tabella:

SELECT * FROM Dogs;

Risultato:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
+-------+-----------+----------+

Possiamo in alternativa usare MAX() funzione invece di MIN() funzione per modificare le righe da eliminare.

Opzione 2

In questo esempio assumeremo che la tabella sia stata ripristinata al suo stato originale (con i duplicati).

Possiamo utilizzare la seguente query per verificare la presenza di righe duplicate:

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
);

Risultato:

+-------+-----------+----------+-------+-----------+----------+
| DogId | FirstName | LastName | DogId | FirstName | LastName |
+-------+-----------+----------+-------+-----------+----------+
|     2 | Bark      | Smith    |     1 | Bark      | Smith    |
|     7 | Wag       | Johnson  |     5 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |     6 | Wag       | Johnson  |
+-------+-----------+----------+-------+-----------+----------+

E possiamo modificare quella query per eliminare i duplicati:

DELETE FROM Dogs WHERE DogId IN (
    SELECT d2.DogId 
    FROM Dogs d1, Dogs d2 
    WHERE d1.FirstName = d2.FirstName 
    AND d1.LastName = d2.LastName 
    AND d1.DogId <> d2.DogId 
    AND d1.DogId=( 
        SELECT MIN(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

Risultato:

Query OK, 3 rows affected (0.075 sec)

Il tavolo è stato ora deduplicato.

Possiamo verificarlo selezionando nuovamente tutte le righe:

SELECT * FROM Dogs;

Risultato:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     1 | Bark      | Smith    |
|     3 | Woof      | Jones    |
|     4 | Ruff      | Robinson |
|     5 | Wag       | Johnson  |
+-------+-----------+----------+

Possiamo usare MAX() invece di MIN() per eliminare le altre righe dai duplicati, se preferisci.