MySQLi - Manejo de duplicados

Las tablas o conjuntos de resultados a veces contienen registros duplicados. A veces, está permitido, pero a veces es necesario detener los registros duplicados. A veces, es necesario identificar registros duplicados y eliminarlos de la tabla. Este capítulo describirá cómo evitar que se produzcan registros duplicados en una tabla y cómo eliminar registros duplicados ya existentes.

Evitar que se produzcan duplicados en una tabla

Puedes usar un PRIMARY KEY o UNIQUEIndexe en una tabla con los campos apropiados para detener registros duplicados. Tomemos un ejemplo: la siguiente tabla no contiene tal índice o clave primaria, por lo que permitiría registros duplicados para el nombre y apellido.

CREATE TABLE person_tbl (
   first_name CHAR(20),
   last_name CHAR(20),
   sex CHAR(10)
);

Para evitar que se creen varios registros con los mismos valores de nombre y apellido en esta tabla, agregue una CLAVE PRIMARIA a su definición. Cuando hace esto, también es necesario declarar que las columnas indexadas NO son NULL, porque una CLAVE PRIMARIA no permite valores NULL -

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10),
   PRIMARY KEY (last_name, first_name)
);

La presencia de un índice único en una tabla normalmente causa un error si inserta un registro en la tabla que duplica un registro existente en la columna o columnas que definen el índice.

Utilizar INSERT IGNORE más bien que INSERT. Si un registro no duplica un registro existente, MySQLi lo inserta como de costumbre. Si el registro es un duplicado, la palabra clave IGNORE le dice a MySQLi que lo descarte silenciosamente sin generar un error.

El siguiente ejemplo no produce errores y, al mismo tiempo, no insertará registros duplicados.

mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT IGNORE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Jay', 'Thomas');
Query OK, 0 rows affected (0.00 sec)

Utilizar REPLACEen lugar de INSERTAR. Si el registro es nuevo, se inserta igual que con INSERT. Si es un duplicado, el nuevo registro reemplaza al anterior:

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 1 row affected (0.00 sec)

mysql> REPLACE INTO person_tbl (last_name, first_name)
   -> VALUES( 'Ajay', 'Kumar');
Query OK, 2 rows affected (0.00 sec)

INSERT IGNORE y REPLACE se deben elegir de acuerdo con el comportamiento de manejo de duplicados que desea realizar. INSERT IGNORE conserva el primero de un conjunto de registros duplicados y descarta el resto. REPLACE conserva el último de un conjunto de duplicados y borra los anteriores.

Otra forma de imponer la singularidad es agregar un índice ÚNICO en lugar de una CLAVE PRIMARIA a una tabla.

CREATE TABLE person_tbl (
   first_name CHAR(20) NOT NULL,
   last_name CHAR(20) NOT NULL,
   sex CHAR(10)
   UNIQUE (last_name, first_name)
);

Contar e identificar duplicados

A continuación se muestra la consulta para contar registros duplicados con first_name y last_name en una tabla.

mysql> SELECT COUNT(*) as repetitions, last_name, first_name
   -> FROM person_tbl
   -> GROUP BY last_name, first_name
   -> HAVING repetitions > 1;

Esta consulta devolverá una lista de todos los registros duplicados en la tabla person_tbl. En general, para identificar conjuntos de valores duplicados, haga lo siguiente:

  • Determine qué columnas contienen los valores que pueden duplicarse.

  • Enumere esas columnas en la lista de selección de columnas, junto con COUNT (*).

  • Enumere también las columnas de la cláusula GROUP BY.

  • Agregue una cláusula HAVING que elimine los valores únicos al requerir que los recuentos de grupos sean mayores que uno.

Eliminar duplicados de un resultado de consulta:

Puedes usar DISTINCT junto con la instrucción SELECT para encontrar registros únicos disponibles en una tabla.

mysql> SELECT DISTINCT last_name, first_name
   -> FROM person_tbl
   -> ORDER BY last_name;

Una alternativa a DISTINCT es agregar una cláusula GROUP BY que nombre las columnas que está seleccionando. Esto tiene el efecto de eliminar duplicados y seleccionar solo las combinaciones únicas de valores en las columnas especificadas:

mysql> SELECT last_name, first_name
   -> FROM person_tbl
   -> GROUP BY (last_name, first_name);

Eliminación de duplicados mediante reemplazo de mesa

Si tiene registros duplicados en una tabla y desea eliminar todos los registros duplicados de esa tabla, este es el procedimiento:

mysql> CREATE TABLE tmp SELECT last_name, first_name, sex
   -> FROM person_tbl;
   -> GROUP BY (last_name, first_name);
mysql> DROP TABLE person_tbl;
mysql> ALTER TABLE tmp RENAME TO person_tbl;

Una forma fácil de eliminar registros duplicados de una tabla es agregar un INDICE o PRIMAY KEY a esa tabla. Incluso si esta tabla ya está disponible, puede utilizar esta técnica para eliminar registros duplicados y también estará seguro en el futuro.

mysql> ALTER IGNORE TABLE person_tbl 
   -> ADD PRIMARY KEY (last_name, first_name);