sql >> Database >  >> RDS >> MariaDB

2 manieren om dubbele rijen in MariaDB te verwijderen (de primaire sleutel wordt genegeerd)

Hier zijn voorbeelden van het verwijderen van dubbele rijen uit een tabel in MariaDB wanneer die rijen een primaire sleutel of een unieke identificatiekolom hebben.

De voorbeelden verwijderen dubbele rijen, maar behouden er een. Dus in het geval van twee identieke rijen, verwijdert het een ervan en behoudt het de andere.

Voorbeeldgegevens

Onze voorbeelden gebruiken de volgende gegevens:

SELECT * FROM Dogs;

Resultaat:

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

We kunnen zien dat de eerste twee rijen duplicaten zijn, evenals de laatste drie rijen.

De DogId kolom unieke waarden bevat (omdat het de primaire sleutel van de tabel is), en daarom zijn er strikt genomen geen duplicaten. Maar in de praktijk wil je vaak tabellen met primaire sleutels ontdubbelen. Daarom negeren we in dit artikel de primaire sleutel en detecteren we dubbele waarden in de overige kolommen.

Optie 1

Laten we onze eerste optie starten door alle rijen te selecteren die zullen worden verwijderd:

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

Resultaat:

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

Om die dubbele rijen te verwijderen, kunnen we de SELECT * om DELETE :

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

Resultaat:

Query OK, 3 rows affected (0.017 sec)

En om het resultaat te verifiëren, kunnen we alle resterende rijen in de tabel selecteren:

SELECT * FROM Dogs;

Resultaat:

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

Als alternatief kunnen we de MAX() . gebruiken functie in plaats van de MIN() functie om te wijzigen welke rijen worden verwijderd.

Optie 2

In dit voorbeeld gaan we ervan uit dat de tabel in de oorspronkelijke staat is hersteld (met de duplicaten).

We kunnen de volgende query gebruiken om te controleren op dubbele rijen:

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

Resultaat:

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

En we kunnen die zoekopdracht aanpassen om de duplicaten te verwijderen:

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

Resultaat:

Query OK, 3 rows affected (0.075 sec)

De tafel is nu ontdubbeld.

We kunnen dit verifiëren door alle rijen opnieuw te selecteren:

SELECT * FROM Dogs;

Resultaat:

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

We kunnen MAX() . gebruiken in plaats van MIN() om desgewenst de andere rijen uit de duplicaten te verwijderen.


  1. Hoe het prestatieprobleem in een relationele database te beschrijven?

  2. Veelvoorkomende MySql-interviewvragen en -antwoorden voor frisser + ervaren

  3. Onderzoek naar de traagheid van PostGIS (editie 2019)

  4. Wachtgebeurtenissen SQL Server -1