Es típico encontrarnos con casos en donde alguien se olvido de colocar una clave única en algún lugar y luego tenemos registros con columnas duplicadas — no me refiero precisamente a claves primarias pero también podría aplicar el caso — y necesitamos eliminarlos pero dejar siempre uno de cada valor único, no es muy compleja la lógica a utilizar pero es una pregunta muy frecuente de como realizar esta tarea.
Para comprender bien la operativa a realizar vamos a hacer un ejemplo muy sencillo, creamos una tabla del abecedario donde no deben existir letras repetidas y cada letra tendrá su PK númerica.
CREATE TABLE abecedario( id in] NOT NULL Primary Key, letra char(1) NOT NULL);
Insertamos 10 filas de ejemplo
id letra ----------- ----- 1 A 2 B 3 C 4 D 5 A 6 E 7 D 8 F 9 F 10 Z (10 filas afectadas)
Para conocer cuales son las letras que estan repetidas podemos ejecutar este query que selecciona las letras y las cuenta, agrupa las letras permitiendo que muestre una sola vez la letra repetida y el al lado muestre la cantidad de repeticiones
select letra, COUNT(*) from abecedario group by letra having COUNT(*) > 1;
Pero esto no basta, solo nos muestra los valores repetidos. Si quisieramos eliminar todos funcionario en un delete, pero el objetivo es eliminar todos los valores duplicados pero dejar uno. Para ello obligatoriamente necesitamos que exista una columna que tenga un identificador único (por ejemplo una PK u otra llave única).
Primero visualizamos cuales serán las filas borradas:
select a1.id ,a1.letra from abecedario a1 inner join abecedario a2 on a1.letra = a2.letra and a1.id > a2.id;
Lo que hizo ese query es crear dos conjuntos de datos de la misma tabla, y unirlas en las columnas que deberian ser unicas y filtrarlas por que no son iguales al primer valor repetido. Para eliminar las filas ejecutariamos lo siguiente:
delete from abecedario where id in ( select a1.id from abecedario a1 inner join abecedario a2 on a1.letra = a2.letra and a1.id > a2.id );
Quedando así la tabla:
id letra ----------- ----- 1 A 2 B 3 C 4 D 6 E 8 F 10 Z (7 filas afectadas)







en
en
GeekZero..,excelente..,muchas gracias capo..!!
Hola, muy aporte, me estoy rompiendo la cabeza con esto porque no tengo una clave unica en la tabla, y es una tabla de informix la cual no hallo como meterle un autoincremental, habra alguna manera de hacerlo sin la clave unica, solo pregunto… ya estoy un poco tapada
Si no tienes una columna que identifique unicamente a cada registro, tienes alguna combinacion de columnas que la identifiquen unicamente?
Me acorde que puedo usar el ROWID que es unico.
Hola. La solución que planteas es perfecta, muy simple, práctica y performante. Funciona 100%. Intente hacer de todo sin tener éxito.
Muchas gracias!
Gracias, me sirvio mucho la clave esta en el id y la comparacion
En mysql seria:
delete a from abecedario AS a,
(select a1.id AS id from abecedario a1
inner join abecedario a2
on a1.letra = a2.letra
and a1.id > a2.id) AS t
where id = t.id;