SQLite
 sql >> Base de Dados >  >> RDS >> SQLite

6 maneiras de selecionar linhas duplicadas no SQLite


As consultas a seguir podem ser usadas para retornar linhas duplicadas no SQLite.

Aqui, as linhas duplicadas contêm valores duplicados em todas as colunas, incluindo a coluna ID.

Dados de amostra


Suponha que temos uma tabela com os seguintes dados:
SELECT * FROM Pets; 

Resultado:
PetId PetName PetType----- ------- -------1 Wag Dog 1 Wag Dog 2 Scratch Cat 3 Tweet Pássaro 4 Bark Dog 4 Bark Dog 4 Bark Dog 

As duas primeiras linhas são duplicadas, assim como as três últimas linhas. Isso porque todas as três colunas contêm os mesmos valores em cada linha duplicada.

Opção 1


Podemos usar a seguinte consulta para ver quantas linhas são duplicadas:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY PetId; 

Resultado:
PetId PetName PetType Count----- ------- ------- -----1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bark Dog 3 
>
Aqui, agrupamos as linhas por todas as colunas e retornamos a contagem de linhas de cada grupo. Isso nos diz se uma linha é única (com uma contagem de 1) ou uma duplicata (com uma contagem maior que 1).

Podemos ordená-lo por contagem em ordem decrescente, para que as linhas com mais duplicatas apareçam primeiro:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY Count(*) DESC; 

Resultado:
PetId PetName PetType Count----- ------- ------- -----4 Bark Dog 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 
>

Opção 2


Se quisermos apenas as linhas duplicadas listadas, podemos usar o HAVING cláusula para retornar apenas linhas com uma contagem maior que 1:
SELECT PetId, PetName, PetType, COUNT(*) AS "Count"FROM PetsGROUP BY PetId, PetName, PetTypeHAVING COUNT(*)> 1ORDER BY PetId; 

Resultado:
PetId PetName PetType Count----- ------- ------- -----1 Wag Dog 2 4 Bark Dog 3 

Opção 3


Outra opção é usar o ROW_NUMBER() função da janela:
SELECT *, ROW_NUMBER() OVER ( PARTITION BY PetId, PetName, PetType ORDER BY PetId, PetName, PetType ) AS Row_NumberFROM Pets; 

Resultado:
PetId PetName PetType Row_Number----- ------- ------- ----------1 Wag Dog 1 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Pássaro 1 4 Cachorro Latido 1 4 Cachorro Latido 2 4 Cachorro Latido 3 

A PARTIÇÃO POR cláusula divide o conjunto de resultados produzido pelo FROM cláusula em partições às quais a função é aplicada. Quando especificamos partições para o conjunto de resultados, cada partição faz com que a numeração comece novamente (ou seja, a numeração começará em 1 para a primeira linha de cada partição).

Opção 4


Podemos usar a consulta acima como uma expressão de tabela comum:
WITH cte AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY PetId, PetName, PetType ORDER BY PetId, PetName, PetType ) AS Row_Number FROM Pets )SELECT * FROM cte WHERE Row_Number <> 1; 

Resultado:
PetId PetName PetType Row_Number----- ------- ------- ----------1 Wag Dog 2 4 Bark Dog 2 4 Bark Dog 3  
Isso retorna apenas as linhas em excesso das duplicatas correspondentes. Portanto, se houver duas linhas idênticas, ele retornará uma delas. Se houver três linhas idênticas, ele retornará duas e assim por diante.

Essa consulta pode ser útil para mostrar quantas linhas serão removidas da tabela em uma operação de desduplicação. Em alguns outros SGBDs (pelo menos no SQL Server), podemos substituir o último SELECT * com EXCLUIR para excluir as linhas duplicadas da tabela. Mas o SQLite não nos deixa atualizar o CTE assim.

Felizmente, as próximas duas opções podem ser modificadas para realizar uma exclusão.

Opção 5


Podemos aproveitar o rowid do SQLite :
SELECT * FROM PetsWHERE EXISTS (SELECT 1 FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType AND Pets.rowid> p2. rowid); 

Resultado:
PetId PetName PetType----- ------- -------1 Wag Dog 4 Lat Dog 4 Lat Dog 

Como é que isso funciona? Por padrão, cada linha no SQLite tem uma coluna especial, geralmente chamada de rowid , que identifica exclusivamente essa linha na tabela. Isso pode ser removido, se necessário, mas, a menos que tenha sido removido explicitamente, você poderá aproveitá-lo em suas consultas.

Opção 6


E finalmente, aqui está outra opção que usa o rowid do SQLite :
SELECT * FROM PetsWHERE rowid> ( SELECT MIN(rowid) FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType); 

Resultado:
PetId PetName PetType----- ------- -------1 Wag Dog 4 Lat Dog 4 Lat Dog