¿Eliminar todas las filas duplicadas excepto una en MySQL? [duplicar]
¿Cómo eliminaría todos los datos duplicados de una tabla MySQL?
Por ejemplo, con los siguientes datos:
SELECT * FROM names;
+----+--------+
| id | name |
+----+--------+
| 1 | google |
| 2 | yahoo |
| 3 | msn |
| 4 | google |
| 5 | google |
| 6 | yahoo |
+----+--------+
Lo usaría SELECT DISTINCT name FROM names;
si fuera una SELECT
consulta.
¿Cómo haría esto DELETE
para eliminar solo los duplicados y mantener solo un registro de cada uno?
Advertencia del editor: esta solución es computacionalmente ineficiente y puede interrumpir la conexión en una tabla grande.
NB: ¡ primero debe hacer esto en una copia de prueba de su tabla!
Cuando lo hice, descubrí que, a menos que también incluyera AND n1.id <> n2.id
, eliminaba todas las filas de la tabla.
Si desea mantener la fila con el
id
valor más bajo:DELETE n1 FROM names n1, names n2 WHERE n1.id > n2.id AND n1.name = n2.name
Si desea mantener la fila con el
id
valor más alto:DELETE n1 FROM names n1, names n2 WHERE n1.id < n2.id AND n1.name = n2.name
Usé este método en MySQL 5.1
No estoy seguro de otras versiones.
Actualización: dado que las personas que buscan en Google para eliminar duplicados terminan aquí.
Aunque la pregunta del OP es sobre DELETE
, tenga en cuenta que usar INSERT
y DISTINCT
es mucho más rápido. Para una base de datos con 8 millones de filas, la siguiente consulta tomó 13 minutos, mientras que usando DELETE
, tomó más de 2 horas y aún así no se completó.
INSERT INTO tempTableName(cellId,attributeId,entityRowId,value)
SELECT DISTINCT cellId,attributeId,entityRowId,value
FROM tableName;
Si desea mantener la fila con el id
valor más bajo:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MIN(n.id)
FROM NAMES n
GROUP BY n.name) x)
Si quieres el id
valor que es el más alto:
DELETE FROM NAMES
WHERE id NOT IN (SELECT *
FROM (SELECT MAX(n.id)
FROM NAMES n
GROUP BY n.name) x)
La subconsulta en una subconsulta es necesaria para MySQL o obtendrás un error 1093.