Her er eksempler på fjernelse af duplikerede rækker fra en tabel i MariaDB, når disse rækker har en primær nøgle eller en unik identifikatorkolonne.
Eksemplerne sletter duplikerede rækker, men beholder én. Så i tilfælde af to identiske rækker, sletter den en af dem og beholder den anden.
Eksempel på data
Vores eksempler bruger følgende 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, at de første to rækker er dubletter, såvel som de sidste tre rækker.
DogId
kolonne indeholder unikke værdier (fordi det er tabellens primære nøgle), og derfor er der strengt taget ingen dubletter. Men i virkelige situationer vil du ofte ønske at de-dupere tabeller, der indeholder primærnøgler. Derfor ignorerer vi i denne artikel den primære nøgle, og vi registrerer duplikerede værdier på tværs af de resterende kolonner.
Mulighed 1
Lad os starte vores første mulighed ved at vælge alle rækker, der vil blive slettet:
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 | +-------+-----------+----------+
For at fjerne disse duplikerede rækker kan vi skifte SELECT *
til 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)
Og for at verificere resultatet kan vi vælge alle resterende rækker i tabellen:
SELECT * FROM Dogs;
Resultat:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +-------+-----------+----------+
Vi kan alternativt bruge MAX()
funktion i stedet for MIN()
funktion for at ændre, hvilke rækker der slettes.
Mulighed 2
I dette eksempel antager vi, at tabellen er blevet gendannet til sin oprindelige tilstand (med dubletterne).
Vi kan bruge følgende forespørgsel til at kontrollere for duplikerede rækker:
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 | +-------+-----------+----------+-------+-----------+----------+
Og vi kan ændre denne forespørgsel for at slette dubletterne:
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 er nu blevet de-duperet.
Vi kan bekræfte dette ved at vælge alle rækker igen:
SELECT * FROM Dogs;
Resultat:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +-------+-----------+----------+
Vi kan bruge MAX()
i stedet for MIN()
for at slette de andre rækker fra dubletterne, hvis det foretrækkes.