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

6 formas de eliminar filas duplicadas que tienen una clave principal en SQLite

A continuación se muestran seis ejemplos que eliminan filas duplicadas de una tabla en SQLite cuando esas filas tienen una clave principal o una columna de identificador único.

En estos casos, la clave principal debe ignorarse al comparar duplicados (debido al hecho de que las claves principales evitan filas duplicadas por definición).

Datos de muestra

Nuestros ejemplos utilizan los siguientes datos:

SELECT * FROM Dogs;

Resultado:

DogId  FirstName  LastName
-----  ---------  --------
1      Bark       Smith   
2      Bark       Smith   
3      Woof       Jones   
4      Ruff       Robinson
5      Wag        Johnson 
6      Wag        Johnson 
7      Wag        Johnson 

Podemos ver que las dos primeras filas contienen duplicados, al igual que las últimas tres filas.

El DogId columna contiene valores únicos (porque es la clave principal de la tabla) y, por lo tanto, estrictamente hablando, no hay duplicados. Pero en situaciones de la vida real, a menudo querrá deduplicar las tablas que contienen claves principales. Por lo tanto, en los siguientes ejemplos ignoramos la clave principal y eliminamos las filas que contienen valores duplicados en las columnas restantes.

Opción 1

Esta es nuestra primera opción para deduplicar la tabla anterior:

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       Robinson
5      Wag        Johnson 

La tabla se ha deduplicado como se esperaba.

Alternativamente, podemos usar el MAX() función en lugar de MIN() función para cambiar qué filas se eliminan. Lo haré en el siguiente ejemplo.

Opción 2

En este ejemplo (y los siguientes ejemplos) asumiremos que la tabla ha sido restaurada a su estado original (con los duplicados).

Aquí hay otra consulta que elimina las filas duplicadas y selecciona las filas 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       Robinson
7      Wag        Johnson 

La tabla ahora ha sido deduplicada.

Note que usé el MAX() función en lugar de MIN() que usé en el ejemplo anterior. Podemos ver el efecto que esto tiene en la operación de eliminación de duplicados. Borró diferentes filas de la tabla.

Opción 3

Aquí hay una opción que no requiere el uso de MIN() o 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;

Resultado:

DogId  FirstName  LastName
-----  ---------  --------
1      Bark       Smith   
3      Woof       Jones   
4      Ruff       Robinson
5      Wag        Johnson 

Opción 4

Aquí hay otra opción:

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       Robinson
5      Wag        Johnson 

Opción 5

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. A menos que se haya eliminado explícitamente de la tabla, puede usar esto como un identificador único para cada fila. Este método podría ser útil si no puede hacer referencia a la clave principal por algún motivo (o si la tabla no tiene una clave principal).

Por lo tanto, podemos usar el rowid en nuestra consulta en lugar del DogId columna:

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       Robinson
5      Wag        Johnson 

Opción 6

Y aquí está el otro ejemplo, pero con rowid en lugar de la clave principal:

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       Robinson
5      Wag        Johnson