Abaixo estão seis exemplos que excluem linhas duplicadas de uma tabela no SQLite quando essas linhas têm uma chave primária ou uma coluna de identificador exclusivo.
Nesses casos, a chave primária deve ser ignorada ao comparar duplicatas (devido ao fato de que as chaves primárias evitam linhas duplicadas por definição).
Dados de amostra
Nossos exemplos usam os seguintes dados:
SELECT * FROM Dogs;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson 6 Wag Johnson 7 Wag Johnson
Podemos ver que as duas primeiras linhas contêm duplicatas, assim como as três últimas linhas.
ODogId
A coluna contém valores únicos (porque é a chave primária da tabela) e, portanto, estritamente falando, não há duplicatas. Mas em situações da vida real, muitas vezes você desejará desduplicar tabelas que contêm chaves primárias. Portanto, nos exemplos a seguir, ignoramos a chave primária e excluímos as linhas que contêm valores duplicados nas colunas restantes.
Opção 1
Aqui está nossa primeira opção para desduplicar a tabela acima:
DELETE FROM Dogs WHERE DogId IN ( SELECT DogId FROM Dogs EXCEPT SELECT MIN(DogId) FROM Dogs GROUP BY FirstName, LastName ); SELECT * FROM Dogs;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson
A tabela foi desduplicada como esperado.
Alternativamente, podemos usar oMAX()
função em vez deMIN()
função para alterar quais linhas são excluídas. Farei isso no próximo exemplo.
Opção 2
Neste exemplo (e nos exemplos a seguir), vamos supor que a tabela foi restaurada ao seu estado original (com as duplicatas).
Aqui está outra consulta que exclui linhas duplicadas e seleciona as linhas restantes:
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;
Resultado:
DogId FirstName LastName----- --------- --------2 Bark Smith 3 Woof Jones 4 Ruff Robinson7 Wag Johnson
A tabela agora foi desduplicada.
Observe que usei oMAX()
função em vez deMIN()
que usei no exemplo anterior. Podemos ver o efeito que isso tem na operação de desduplicação. Ele excluiu diferentes linhas da tabela.
Opção 3
Aqui está uma opção que não requer o uso deMIN()
ouMAX()
:
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;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOpção 4
Aqui está outra opção:
DELETE FROM Dogs WHERE DogId > ( SELECT MIN(DogId) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOpção 5
Por padrão, cada linha no SQLite tem uma coluna especial, geralmente chamada derowid
, que identifica exclusivamente essa linha na tabela. A menos que tenha sido explicitamente removido da tabela, você pode usá-lo como um identificador exclusivo para cada linha. Esse método pode ser útil se você não conseguir referenciar a chave primária por algum motivo (ou se a tabela não tiver uma chave primária).
Podemos, portanto, usar orowid
em nossa consulta em vez doDogId
coluna:
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;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag JohnsonOpção 6
E aqui está o outro exemplo, mas comrowid
em vez da chave primária:
DELETE FROM Dogs WHERE rowid > ( SELECT MIN(rowid) FROM Dogs d2 WHERE Dogs.FirstName = d2.FirstName AND Dogs.LastName = d2.LastName ); SELECT * FROM Dogs;
Resultado:
DogId FirstName LastName----- --------- --------1 Bark Smith 3 Woof Jones 4 Ruff Robinson5 Wag Johnson