sql >> Base de Datos >  >> RDS >> SQLite

6 formas de seleccionar filas duplicadas en SQLite

Las siguientes consultas se pueden usar para devolver filas duplicadas en SQLite.

Aquí, las filas duplicadas contienen valores duplicados en todas las columnas, incluida la columna ID.

Datos de muestra

Supongamos que tenemos una tabla con los siguientes datos:

SELECT * FROM Pets;

Resultado:

PetId  PetName  PetType
-----  -------  -------
1      Wag      Dog    
1      Wag      Dog    
2      Scratch  Cat    
3      Tweet    Bird   
4      Bark     Dog    
4      Bark     Dog    
4      Bark     Dog    

Las dos primeras filas son duplicados, al igual que las últimas tres filas. Eso es porque las tres columnas contienen los mismos valores en cada fila duplicada.

Opción 1

Podemos usar la siguiente consulta para ver cuántas filas están duplicadas:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY PetId;

Resultado:

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

Aquí, agrupamos las filas por todas las columnas y devolvimos el recuento de filas de cada grupo. Esto nos dice si una fila es única (con un recuento de 1) o un duplicado (con un recuento superior a 1).

Podemos ordenarlo por conteo en orden descendente, de modo que las filas con más duplicados aparezcan primero:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
ORDER BY Count(*) DESC;

Resultado:

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

Opción 2

Si solo queremos que se enumeren las filas duplicadas, podemos usar HAVING cláusula para devolver solo filas con un recuento mayor que 1:

SELECT 
    PetId,
    PetName,
    PetType,
    COUNT(*) AS "Count"
FROM Pets
GROUP BY 
    PetId,
    PetName,
    PetType
HAVING COUNT(*) > 1
ORDER BY PetId;

Resultado:

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

Opción 3

Otra opción es usar el ROW_NUMBER() función de ventana:

SELECT 
    *, 
    ROW_NUMBER() OVER ( 
        PARTITION BY PetId, PetName, PetType 
        ORDER BY PetId, PetName, PetType
        ) AS Row_Number
FROM Pets;

Resultado:

PetId  PetName  PetType  Row_Number
-----  -------  -------  ----------
1      Wag      Dog      1         
1      Wag      Dog      2         
2      Scratch  Cat      1         
3      Tweet    Bird     1         
4      Bark     Dog      1         
4      Bark     Dog      2         
4      Bark     Dog      3         

La PARTITION BY cláusula divide el conjunto de resultados producido por FROM cláusula en particiones a las que se aplica la función. Cuando especificamos particiones para el conjunto de resultados, cada partición hace que la numeración comience de nuevo (es decir, la numeración comenzará en 1 para la primera fila de cada partición).

Opción 4

Podemos usar la consulta anterior como una expresión de tabla común:

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         

Esto devuelve solo el exceso de filas de los duplicados coincidentes. Entonces, si hay dos filas idénticas, devuelve una de ellas. Si hay tres filas idénticas, devuelve dos, y así sucesivamente.

Esta consulta puede ser útil para mostrar cuántas filas se eliminarán de la tabla en una operación de eliminación de duplicados. En algunos otros DBMS (al menos en SQL Server), podemos reemplazar el último SELECT * con DELETE para eliminar las filas duplicadas de la tabla. Pero SQLite no nos permitirá actualizar el CTE de esa manera.

Afortunadamente, las siguientes dos opciones se pueden modificar para realizar una eliminación.

Opción 5

Podemos aprovechar el rowid de SQLite :

SELECT * FROM Pets
WHERE 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      Bark     Dog    
4      Bark     Dog    

¿Como funciona esto? De forma predeterminada, cada fila en SQLite tiene una columna especial, generalmente llamada rowid , que identifica de forma única esa fila dentro de la tabla. Esto se puede eliminar si es necesario, pero a menos que se haya eliminado explícitamente, podrá aprovecharlo en sus consultas.

Opción 6

Y finalmente, aquí hay otra opción que usa el rowid de SQLite :

SELECT * FROM Pets
WHERE 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      Bark     Dog    
4      Bark     Dog