Poniżej znajduje się sześć przykładów, które usuwają zduplikowane wiersze z tabeli w SQLite, gdy te wiersze mają klucz podstawowy lub kolumnę unikatowego identyfikatora.
W takich przypadkach klucz podstawowy musi zostać zignorowany podczas porównywania duplikatów (ze względu na fakt, że klucze podstawowe z definicji zapobiegają duplikowaniu wierszy).
Przykładowe dane
Nasze przykłady wykorzystują następujące dane:
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson 6 Wag Johnson 7 Wag Johnson
Widzimy, że pierwsze dwa wiersze zawierają duplikaty, podobnie jak ostatnie trzy wiersze.
DogId
kolumna przechowuje unikalne wartości (ponieważ jest to klucz podstawowy tabeli), a zatem, ściśle mówiąc, nie ma duplikatów. Jednak w rzeczywistych sytuacjach często będziesz chciał usunąć duplikaty tabel zawierających klucze podstawowe. Dlatego w poniższych przykładach ignorujemy klucz podstawowy i usuwamy wiersze zawierające zduplikowane wartości w pozostałych kolumnach.
Opcja 1
Oto nasza pierwsza opcja usuwania duplikatów powyższej tabeli:
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Tabela została usunięta zgodnie z oczekiwaniami.
Alternatywnie możemy użyć MAX()
funkcja zamiast MIN()
funkcja do zmiany, które wiersze są usuwane. Zrobię to w następnym przykładzie.
Opcja 2
W tym przykładzie (i w poniższych przykładach) założymy, że tabela została przywrócona do swojego pierwotnego stanu (z duplikatami).
Oto inne zapytanie, które usuwa zduplikowane wiersze i wybiera pozostałe:
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 MAX(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
)
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 7 Wag Johnson
Tabela została usunięta z kopii.
Zauważ, że użyłem MAX()
funkcja zamiast MIN()
którego użyłem w poprzednim przykładzie. Widzimy wpływ, jaki ma to na operację usuwania duplikatów. Usunął różne wiersze z tabeli.
Opcja 3
Oto opcja, która nie wymaga użycia MIN()
lub MAX()
:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.DogId > d2.DogId
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Opcja 4
Oto kolejna opcja:
DELETE FROM Dogs
WHERE DogId > (
SELECT MIN(DogId) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Opcja 5
Domyślnie każdy wiersz w SQLite ma specjalną kolumnę, zwykle nazywaną rowid
, który jednoznacznie identyfikuje ten wiersz w tabeli. O ile nie został jawnie usunięty z tabeli, możesz użyć go jako unikalnego identyfikatora dla każdego wiersza. Ta metoda może być przydatna, jeśli z jakiegoś powodu nie możesz odwołać się do klucza podstawowego (lub jeśli tabela nie ma klucza podstawowego).
Możemy zatem użyć rowid
w naszym zapytaniu zamiast DogId
kolumna:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.rowid > d2.rowid
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
Opcja 6
A oto drugi przykład, ale z rowid
zamiast klucza podstawowego:
DELETE FROM Dogs
WHERE rowid > (
SELECT MIN(rowid) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
Wynik:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson