DENSE_RANK
y para qué se usa?
DENSE_RANK
es una función de ventana que devuelve el rango de cada fila dentro de una partición (grupo), ordenado según la columna o columnas especificadas en la cláusula ORDER BY
. Si varias filas tienen el mismo valor en el criterio de orden, comparten el mismo rango, y la siguiente fila tendrá el rango siguiente inmediato (sin saltos).
Se usa en escenarios como:
DENSE_RANK
DENSE_RANK() OVER ( [PARTITION BY column1, column2, ...] ORDER BY column_name [ASC|DESC] )
PARTITION BY
: (Opcional) Divide el conjunto de resultados en particiones o grupos, y reinicia la numeración para cada partición.
ORDER BY
: Especifica cómo se deben ordenar las filas dentro de cada partición (o del conjunto completo).
RANK
, DENSE_RANK
y ROW_NUMBER
RANK
: Asigna el mismo rango a filas con valores idénticos, pero deja huecos en la numeración para la siguiente fila (por ejemplo, 1, 2, 2, 4).
DENSE_RANK
: Asigna el mismo rango a valores iguales, pero no deja huecos en la secuencia de rangos (por ejemplo, 1, 2, 2, 3).
ROW_NUMBER
: Asigna un número único a cada fila, sin considerar empates.
DENSE_RANK
Supongamos que tienes una tabla Empleados
con las columnas EmpleadoID
, Nombre
y Salario
, y quieres clasificar a los empleados según su salario en orden descendente:
SELECT EmpleadoID, Nombre, Salario,
DENSE_RANK() OVER (ORDER BY Salario DESC) AS RangoSalario
FROM Empleados;
Resultado:
EmpleadoID | Nombre | Salario | RangoSalario
-----------|---------|---------|-------------
1 | Ana | 5000 | 1
3 | Juan | 4500 | 2
4 | Luis | 4500 | 2
5 | Pedro | 3500 | 3
Las filas con el mismo salario (Juan
y Luis
) reciben el mismo rango (2), y el siguiente rango es 3 (sin saltar números).
Si deseas clasificar a los empleados dentro de cada departamento según sus ventas, utiliza la cláusula PARTITION BY
para agrupar por Departamento
:
SELECT Departamento, EmpleadoID, Nombre, Ventas,
DENSE_RANK() OVER (PARTITION BY Departamento ORDER BY Ventas DESC) AS RangoVentas
FROM Empleados;
Resultado:
Departamento | EmpleadoID | Nombre | Ventas | RangoVentas
-------------|------------|--------|--------|------------
Ventas | 1 | Ana | 1500 | 1
Ventas | 2 | Luis | 1300 | 2
Ventas | 3 | Juan | 1300 | 2
Soporte | 4 | Pedro | 900 | 1
Soporte | 5 | Marta | 700 | 2
El ranking se reinicia para cada Departamento
, calculando los rangos dentro de cada grupo de manera independiente.
Si tienes una tabla Productos
con las columnas Categoria
, NombreProducto
y Ventas
, y deseas encontrar los 3 productos más vendidos por categoría:
WITH RankingProductos AS (
SELECT Categoria, NombreProducto, Ventas,
DENSE_RANK() OVER (PARTITION BY Categoria ORDER BY Ventas DESC) AS RangoVentas
FROM Productos
)
SELECT Categoria, NombreProducto, Ventas
FROM RankingProductos
WHERE RangoVentas <= 3;
Resultado:
Categoria | NombreProducto | Ventas
------------|----------------|-------
Electrónica | TV | 2000
Electrónica | Laptop | 1500
Electrónica | Tablet | 1200
Muebles | Sofá | 900
Muebles | Mesa | 800
Muebles | Silla | 700
La consulta devuelve solo los 3 productos con mayor volumen de ventas dentro de cada categoría.
Puedes usar DENSE_RANK
para identificar y eliminar duplicados, manteniendo solo la primera aparición de cada conjunto de valores:
WITH Duplicados AS (
SELECT *,
DENSE_RANK() OVER (PARTITION BY Nombre ORDER BY EmpleadoID) AS Rango
FROM Empleados
)
DELETE FROM Duplicados WHERE Rango > 1;
Esto elimina todas las filas que tengan un rango mayor a 1, manteniendo solo la primera fila para cada nombre.
N
productos más vendidos en general
Si quieres ver solo los 3 productos más vendidos en todo el conjunto de datos:
SELECT NombreProducto, Ventas,
DENSE_RANK() OVER (ORDER BY Ventas DESC) AS Rango
FROM Productos
WHERE DENSE_RANK() OVER (ORDER BY Ventas DESC) <= 3;
Este ejemplo devuelve los 3 productos más vendidos, independientemente de su categoría.
DENSE_RANK
requiere una cláusula ORDER BY
dentro de la cláusula OVER
para definir cómo se calculan los rangos.
DENSE_RANK
puede verse afectado en tablas grandes con muchos grupos o particiones, especialmente si se usa en combinación con muchas columnas en ORDER BY
.
DENSE_RANK
no deja huecos en la numeración de rangos, lo cual lo diferencia de RANK
, que sí lo hace en casos de empate.
Para más información sobre DENSE_RANK
, consulta la documentación oficial de Microsoft.
Jorge García
Fullstack developer