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