sql >> Base de Datos >  >> RDS >> MariaDB

2 formas de eliminar filas duplicadas en MariaDB (ignora la clave principal)

Estos son ejemplos de eliminación de filas duplicadas de una tabla en MariaDB cuando esas filas tienen una clave principal o una columna de identificador único.

Los ejemplos eliminan filas duplicadas pero conservan una. Entonces, en el caso de dos filas idénticas, elimina una de ellas y mantiene la otra.

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 están duplicadas, así como 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 este artículo ignoramos la clave principal y detectamos valores duplicados en las columnas restantes.

Opción 1

Comencemos nuestra primera opción seleccionando todas las filas que se eliminarán:

SELECT * FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

Resultado:

+-------+-----------+----------+
| DogId | FirstName | LastName |
+-------+-----------+----------+
|     2 | Bark      | Smith    |
|     6 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |
+-------+-----------+----------+

Para eliminar esas filas duplicadas, podemos cambiar SELECT * para DELETE :

DELETE FROM Dogs 
WHERE DogId IN (
    SELECT DogId FROM Dogs 
    EXCEPT SELECT MIN(DogId) FROM Dogs 
    GROUP BY FirstName, LastName
    );

Resultado:

Query OK, 3 rows affected (0.017 sec)

Y para verificar el resultado, podemos seleccionar todas las filas restantes de la tabla:

SELECT * FROM Dogs;

Resultado:

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

También podemos usar el MAX() función en lugar de MIN() función para cambiar qué filas se eliminan.

Opción 2

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

Podemos usar la siguiente consulta para buscar filas duplicadas:

SELECT * 
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
);

Resultado:

+-------+-----------+----------+-------+-----------+----------+
| DogId | FirstName | LastName | DogId | FirstName | LastName |
+-------+-----------+----------+-------+-----------+----------+
|     2 | Bark      | Smith    |     1 | Bark      | Smith    |
|     7 | Wag       | Johnson  |     5 | Wag       | Johnson  |
|     7 | Wag       | Johnson  |     6 | Wag       | Johnson  |
+-------+-----------+----------+-------+-----------+----------+

Y podemos modificar esa consulta para eliminar los duplicados:

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 MIN(DogId) 
        FROM Dogs d3 
        WHERE d3.FirstName = d1.FirstName 
        AND d3.LastName = d1.LastName
    )
);

Resultado:

Query OK, 3 rows affected (0.075 sec)

La tabla ahora ha sido deduplicada.

Podemos verificar esto seleccionando todas las filas nuevamente:

SELECT * FROM Dogs;

Resultado:

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

Podemos usar MAX() en lugar de MIN() para eliminar las otras filas de los duplicados si lo prefiere.