¿Cómo eliminar registros duplicados de una tabla en MySQL / MariaDB?
Acepto que este no es un problema al que me enfrento todos los días y menos en este gestor de bases de datos. En los demás motores como Oracle y PostgreSQL no había tenido ese problema (hasta donde recuerdo). Pero hoy tuve la necesidad de eliminar algunos registros duplicados de una tabla de un cliente (él deseaba eliminar los registros duplicados de sus clientes).
Al solicitarme el trabajo procedí a usar una sentencia del estilo:
DELETE FROM Customer cc
WHERE cc.email IN (
SELECT c.email
FROM Customer c
...
HAVING count(c.email)>1
)
Sencillo, práctico e intuitivo, ¿no? Le digo al gestor de base de datos que elimine los registros de la tabla Customer que tienen más de una incidencia. Pero tal fue mi sorpresa que me encontré con el siguiente error:
Error: #1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'cc WHERE cc.email IN (SELECT c.email FROM Customer c' at line 1
Y en algún momento me encontré con un error como:
#1093 - You can't specify target table 'Customer' for update in FROM clause
Así que entonces empezó la labor de investigación (¿o quise decir el dolor de cabeza?). Luego de visitar una buena cantidad de páginas web relacionadas, la documentación de MySQL (que por cierto no menciona qué hacer en esos casos), encontré que situaciones como la que necesitaba se resuelve con una eliminación relacional (algo que creo solo existe en MySQL/MariaDB). Para mi caso la consulta quedó así:
DELETE FROM Customer
USING Customer, Customer as c
WHERE (NOT Customer.id=c.id)
AND (Customer.email=c.email)
¿Alguna duda? Sé que no es tan intuitiva como la primera sentencia, pero luego de revisarla detenidamente tuvo sentido para mí. Básicamente lo que hace la sentencia es decir que elimine de Customer haciendo una relación con Customer (con la misma tabla) en donde el ID sea diferente y el email se igual.
La anterior sentencia tiene un pequeño y grave problema: Borra todos los registros que se enuentran duplicados, conservando los que no lo están. Averiguando en diferentes sitios encontré la solución ideal en CommentÇaMarche:
ALTER IGNORE TABLE TabTest ADD UNIQUE INDEX(x,y);
En donde los campos del índice son los que deseamos verificar que sean únicos, no repetidos, borrando del segundo en adelante.
Espero ahorrarles la búsqueda y desde luego dolores de cabeza.
junio 21st, 2010 at 1:12 PM
Hola. tengo problemas con un update, estoy haciendo una practica de ejercicios de mysql
este es el codigo, como deberia corregirlo?. la consulta es actualizar a todos los trabajadores supervisados por C. COULOMB, como referencia a la misma tabla da el error.
UPDATE `trabajador`
SET tarifa = tarifa * 0.05
WHERE id_supv = (SELECT id_t
FROM `trabajador`
WHERE nombre = ‘C. COULOMB’)
octubre 11th, 2010 at 4:18 AM
Hola…
En una prueba con tu consulta se borran los duplicados y el original, como se haria para que deje uno de los dos??
Gracias.
noviembre 8th, 2010 at 3:12 PM
Es cierto, no lo había notado. Acabo de actualizar el post indicando la sentencia para conservar solo uno de los registros.