Tabla
| ID | V1 | V2 |
| 1 | a | b |
| 2 | a | a |
| 3 | a | b |
| 4 | x | y |
| 5 | x | y |
| 6 | x | y |
| 7 | a | x |
La página indicaba que la consulta tenía que ejecutarse correctamente en SQL Server. Yo planteé la siguiente solución que no sólo funciona en SQL Server sino en la mayoría de los gestores de bases de datos:
DELETE FROM tabla WHERE id > (SELECT MIN(id) FROM tabla as b WHERE b.v1=tabla.v1 AND b.v2 = tabla.v2)
El funcionamiento de la consulta es el siguiente:
- La consulta exterior recorre cada registro de la tabla.
- La consulta interior toma como «parámetros» los campos V1 y V2 de la consulta exterior.
- La consulta exterior calcula el mínimo valor «ID» para cada combinación de V1 y V2.
- Una vez que la consulta interior termina, la consulta exterior borra aquellos registros de V1 y V2 cuya «ID» es mayor que la mínima «ID» calculada para esa combinación de V1 y V2. Esto dejará aquellas combinaciones de V1 y V2 cuya clave primaria es mínina.
Puede cambiarse la consulta para que borre aquellos registros que sean «menores» que el «máximo» o también para que borre aquellos registros que sean «distintos» al «máximo». O «distintos» al «mínimo». Ejemplo:
- DELETE FROM tabla WHERE id < (SELECT MAX(id) FROM tabla as b WHERE b.v1=tabla.v1 AND b.v2 = tabla.v2)
- DELETE FROM tabla WHERE id <> (SELECT MAX(id) FROM tabla as b WHERE b.v1=tabla.v1 AND b.v2 = tabla.v2)
- DELETE FROM tabla WHERE id <> (SELECT MIN(id) FROM tabla as b WHERE b.v1=tabla.v1 AND b.v2 = tabla.v2)
El problema se centraba en sólo eliminar los registros pero no tomaba en cuenta otros elementos: ¿Qué pasaría si los registros borrados tenían relaciones con otras tablas?
Necesariamente habría que realizar una consulta que realizara la actualización de las otras tablas para que usaran las claves primarias que quedarían «vivas» luego de la eliminación de los registros repetidos.
Esto se deja como ejercicio al lector.
No hay comentarios:
Publicar un comentario