27 de marzo de 2009

Cómo eliminar registros duplicados rapidamente en MySQL

Cuando importamos datos desde una hoja de cálculo a una base de datos nos encontramos casi siempre con un "problema" muy común: los registros repetidos. Si en nuestra nueva tabla importada necesitamos asignar una clave primaria, parecerá algo imposible, pero la verdad es que podemos solucionar el tema de una forma muy sencilla.

Veamos el proceso desde el principio. Supongamos una sencilla tabla de prueba con un par de campos:


mysql> create table repetidos(dni char(9), nombre varchar(50));
Query OK, 0 rows affected (0.06 sec)


Insertamos unos cuantos registros, uno de ellos repetido:


mysql> insert into repetidos values('11111111A','Eva Gonzalez');
Query OK, 1 row affected (0.00 sec)

mysql> insert into repetidos values('22222222B','Luis Carrizo');
Query OK, 1 row affected (0.00 sec)

mysql> insert into repetidos values('11111111A','Eva Gonzalez');
Query OK, 1 row affected (0.00 sec)


Como la tabla no tiene ningún índice único, no hemos tenido problemas en la inserción (o en la importación comentada):


mysql> select * from repetidos;
+-----------+--------------+
| dni | nombre |
+-----------+--------------+
| 11111111A | Eva Gonzalez |
| 22222222B | Luis Carrizo |
| 11111111A | Eva Gonzalez |
+-----------+--------------+
3 rows in set (0.00 sec)


Si intentamos crear un índice único (una clave primaria en este caso) en el campo DNI, comenzarán los problemas:


mysql> alter table repetidos add primary key(dni);
ERROR 1062 (23000): Entrada duplicada '11111111A' para la clave 1


Sin embargo podemos controlar la forma en cómo ALTER TABLE gestiona este tema utilizando IGNORE en la instrucción. Los registros duplicados se borrarán quedando sólo el primer registro duplicado:


mysql> ALTER IGNORE TABLE repetidos ADD PRIMARY KEY(dni);
Query OK, 3 rows affected (0.01 sec)
Registros: 3 Duplicados: 1 Peligros: 0


Y compruebo finalmente como he conseguido mi objetivo:


mysql> select * from repetidos;
+-----------+--------------+
| dni | nombre |
+-----------+--------------+
| 11111111A | Eva Gonzalez |
| 22222222B | Luis Carrizo |
+-----------+--------------+
2 rows in set (0.00 sec)

Y efectivamente he conseguido tener además mi clave primaria:

mysql> show create table repetidos\G
*************************** 1. row ***************************
Table: repetidos
Create Table: CREATE TABLE `repetidos` (
`dni` char(9) NOT NULL default '',
`nombre` varchar(50) default NULL,
PRIMARY KEY (`dni`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)