sql >> Databasteknik >  >> RDS >> MariaDB

2 sätt att ta bort dubbletter av rader i MariaDB (ignorerar primärnyckel)

Här är exempel på att ta bort dubbletter av rader från en tabell i MariaDB när dessa rader har en primärnyckel eller unik identifierarkolumn.

Exemplen tar bort dubbletter av rader men behåller en. Så i fallet med två identiska rader tar den bort en av dem och behåller den andra.

Exempeldata

Våra exempel använder följande data:

SELECT * FROM Dogs;

Resultat:

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

Vi kan se att de två första raderna är dubbletter, liksom de tre sista raderna.

DogId kolumnen innehåller unika värden (eftersom det är tabellens primärnyckel), och därför finns det strängt taget inga dubbletter. Men i verkliga situationer vill du ofta de-dupera tabeller som innehåller primärnycklar. Därför ignorerar vi den primära nyckeln i den här artikeln och vi upptäcker dubbletter av värden över de återstående kolumnerna.

Alternativ 1

Låt oss börja vårt första alternativ genom att välja alla rader som kommer att raderas:

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

Resultat:

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

För att ta bort dessa dubbletter av raderna kan vi byta SELECT * till DELETE :

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

Resultat:

Query OK, 3 rows affected (0.017 sec)

Och för att verifiera resultatet kan vi välja alla återstående rader i tabellen:

SELECT * FROM Dogs;

Resultat:

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

Vi kan alternativt använda MAX() funktion istället för MIN() funktion för att ändra vilka rader som tas bort.

Alternativ 2

I det här exemplet antar vi att tabellen har återställts till sitt ursprungliga tillstånd (med dubbletter).

Vi kan använda följande fråga för att leta efter dubbletter av rader:

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

Resultat:

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

Och vi kan ändra den frågan för att ta bort dubbletterna:

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

Resultat:

Query OK, 3 rows affected (0.075 sec)

Tabellen har nu avduperats.

Vi kan verifiera detta genom att markera alla rader igen:

SELECT * FROM Dogs;

Resultat:

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

Vi kan använda MAX() istället för MIN() för att ta bort de andra raderna från dubbletterna om så önskas.


  1. De bästa AWR-användbara frågorna för R12.2/R12.1-uppgradering

  2. Hur man lägger till 'ON DELETE CASCADE' i ALTER TABLE-satsen

  3. HAProxy Connections vs MySQL Connections - Vad du bör veta

  4. Oracle INSERT i två tabeller i en fråga