По-долу са шест примера, които изтриват дублиращи се редове от таблица в SQLite, когато тези редове имат първичен ключ или колона с уникален идентификатор.
В тези случаи първичният ключ трябва да се игнорира при сравняване на дубликати (поради факта, че първичните ключове предотвратяват дублиране на редове по дефиниция).
Примерни данни
Нашите примери използват следните данни:
SELECT * FROM Dogs;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag Johnson предварително>Можем да видим, че първите два реда съдържат дубликати, както и последните три реда.
DogId
колоната съдържа уникални стойности (защото е първичен ключ на таблицата) и следователно, строго погледнато, няма дубликати. Но в ситуации от реалния живот често ще искате да премахнете фалшивите таблици, които съдържат първични ключове. Следователно в следващите примери игнорираме първичния ключ и изтриваме редове, които съдържат дублиращи се стойности в останалите колони.Опция 1
Ето първата ни опция за премахване на дубликата на горната таблица:
DELETE FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName ); SELECT * FROM Dogs;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonТаблицата е премахната, както се очакваше.
Като алтернатива можем да използваме
MAX()
функция вместоMIN()
функция за промяна на кои редове се изтриват. Ще направя това в следващия пример.Опция 2
В този пример (и следващите примери) ще приемем, че таблицата е възстановена в първоначалното си състояние (с дубликатите).
Ето още една заявка, която изтрива дублиращи се редове и избира останалите:
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;
Резултат:
DogId Име Фамилия----- --------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag JohnsonТаблицата вече е премахната.
Забележете, че използвах
MAX()
функция вместоMIN()
който използвах в предишния пример. Можем да видим влиянието, което това оказва върху операцията за премахване на дуппинга. Той изтри различни редове от таблицата.Опция 3
Ето опция, която не изисква използването на
MIN()
или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;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonОпция 4
Ето още една опция:
DELETE FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonОпция 5
По подразбиране всеки ред в SQLite има специална колона, обикновено наричана
rowid
, който уникално идентифицира този ред в таблицата. Освен ако не е изрично премахнат от таблицата, можете да го използвате като уникален идентификатор за всеки ред. Този метод може да бъде полезен, ако по някаква причина не можете да посочите първичния ключ (или ако таблицата няма първичен ключ).Следователно можем да използваме
rowid
в нашата заявка вместоDogId
колона: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;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonОпция 6
И ето другия пример, но с
rowid
вместо първичния ключ:DELETE FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Резултат:
DogId Име Фамилия----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson