sábado, 15 de septiembre de 2018

ELIMINAR REGISTROS DUPLICADOS


Si utilizamos el “Asistente para búsqueda de duplicados” de Access para crear una consulta que nos permita eliminar registros duplicados, nos encontraremos con el problema de que también borraremos los registros originales, es decir, en vez de mover los repetidos y dejar uno, los eliminaremos todos.
De las diversas formas que hay para abordar correctamente esta tarea, a mí me gusta particularmente la que a continuación explico, pues permite definir nítidamente cual es el registro “original” o “primero” que no hay que eliminar.
Como siempre utilizaré un ejemplo para ilustrar el método:

--Tabla de ejemplo
Create Table Alumnos (Id Counter Primary Key, Nombre Text (100), DNI Text (9));

--Insertamos valores en la tabla (algunos de ellos duplicados)
Insert Into Alumnos (Nombre, DNI) Values ("Alumno1", "12345678A");
Insert Into Alumnos (Nombre, DNI) Values ("Alumno2", "12345678B");
Insert Into Alumnos (Nombre, DNI) Values ("Alumno3", "12345678C");
Insert Into Alumnos (Nombre, DNI) Values ("Alumno1", "12345678A");
Insert Into Alumnos (Nombre, DNI) Values ("Alumno1", "12345678A");

--Este es el codigo sql propuesto:
Delete Alumnos.*
From Alumnos
Where Alumnos.Id Not In
       (
             Select First(Id)
             From
                    (
                           Select Top 100 Percent Alumnos.*
                           From Alumnos
                           Order By Nombre, DNI, Id
                    )
             Group By Nombre, DNI
       )
      
--Comprobamos los resultados:
Select * From Alumnos

Resultados
Id
Nombre
DNI
1
Alumno1
12345678A
2
Alumno2
12345678B
3
Alumno3
12345678C

Explicación: en la clausula Where excluimos los registros devueltos por una subconsulta. En esta mostramos el primer Id (campo clave) de cada conjunto susceptible de ser un duplicado (Alumno y DNI, aunque probablemente con este último seria suficiente), para ello, agrupamos por Nombre y DNI y obtenemos el primer Id mediante First. Para asegurarnos que el Id devuelto sea el “primero” es imprescindible establecer un criterio de ordenación por lo que en vez de basar la subconsulta directamente sobre la tabla Alumnos, utilizamos una tabla derivada donde empleamos el predicado Top y establecemos un orden. En este punto cabe recordar que cualquier instrucción “Order By” que no esté dentro de una consulta de selección (afectando directamente al orden de los resultados finales,) va a ser ignorada por el motor sql de Access, a no ser que utilicemos el predicado Top. La palabra reservada Percent se utiliza para especificar un porcentaje de registros a devolver sobre el total. Puesto que no es esta la intención, el valor de Percent lo establecemos a 100 (la totalidad de registros).

Ramon Poch. Terrassa, a 15/09/2018