La extracción de registros únicos en SQL se ha vuelto una tarea crítica con la transición masiva de las organizaciones hacia el almacenamiento de datos multidimensionales. A veces se requiere mostrar filas no repetidas por la combinación de varias columnas, otras veces solo por una clave.
Historia de la pregunta:
Las primeras versiones de SQL solo ofrecían DISTINCT para filtrar duplicados. Luego aparecieron técnicas estructurales, incluyendo GROUP BY para agregaciones de conjuntos únicos de valores y funciones de ventana como ROW_NUMBER() para escenarios más flexibles de manejo de duplicados, por ejemplo: selección por el "último" o "primer" registro.
Problema:
DISTINCT solo funciona a nivel del conjunto de campos en SELECT, mientras que GROUP BY requiere agregaciones. Las funciones de ventana permiten lógica avanzada, pero su uso a menudo provoca errores si no se planifica el orden de selección de filas. A menudo, los desarrolladores confunden estos enfoques, lo que lleva a resultados incorrectos.
Solución:
Ejemplo de código:
Obtener un último registro de pedidos por cada cliente:
WITH OrdersRank AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) as rn FROM Orders ) SELECT * FROM OrdersRank WHERE rn = 1;
Características clave:
¿Se puede usar DISTINCT junto con funciones agregadas sin GROUP BY?
No, las funciones agregadas requieren agrupamiento, de lo contrario habrá un error de sintaxis.
SELECT COUNT(DISTINCT CustomerID) -- correcto SELECT SUM(Amount), DISTINCT CustomerID -- ¡error!
¿Qué sucederá si en GROUP BY no se indican todos los campos no agregados de SELECT?
Esto causará un error en la mayoría de los SGBD: todos los campos en SELECT, excepto los agregados, deben estar enumerados en GROUP BY.
¿Se pueden "eliminar" duplicados usando funciones de ventana sin subconsulta?
No: el uso de ROW_NUMBER() dentro de un solo SELECT no filtra automáticamente "repeticiones", se necesita una consulta externa para seleccionar las filas requeridas.
Se eligió DISTINCT en todas las columnas para una tabla de 20 millones de filas: la consulta tardó horas, resultado — time-out o caída de rendimiento de la base de datos.
Ventajas:
Desventajas:
Se utilizaron funciones de ventana: se obtuvo solo el último registro necesario por cliente en milisegundos; los anteriores y duplicados no se cargaron.
Ventajas:
Desventajas: