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.