Contenido de esta guía
La diferencia en una frase
RANK deja huecos después de un empate; DENSE_RANK continúa con la posición siguiente sin huecos. Ambas asignan la misma posición a filas que son iguales según el ORDER BY de la ventana.
Qué pregunta responde cada una
Utiliza RANK cuando la posición debe reflejar cuántas filas aparecen antes. En una competición, dos personas empatadas en primer lugar pueden ir seguidas por el tercer puesto.
Utiliza DENSE_RANK cuando quieres numerar niveles o grupos de valores distintos. Después de dos filas en el nivel 1, el siguiente valor distinto ocupa el nivel 2.
No existe una opción universalmente mejor: la elección depende del significado de la clasificación.
Sintaxis
RANK() OVER (ORDER BY columna DESC)
DENSE_RANK() OVER (ORDER BY columna DESC)Para obtener una clasificación con significado, define un ORDER BY dentro de OVER. SQL Server lo exige sintácticamente; PostgreSQL y SQLite permiten omitirlo, pero entonces el orden no queda definido para una clasificación útil. En SQLite, sin ORDER BY, todas las filas se consideran pares y tanto RANK como DENSE_RANK devuelven 1. Si no quieres romper los empates, no añadas una columna única como id dentro del orden de la ventana.
Ejemplo guiado con empates
| id | total |
|---|---|
| 108 | 249.0 |
| 111 | 249.0 |
| 114 | 203.9 |
| 104 | 179.0 |
| 118 | 179.0 |
SELECT id,
total,
RANK() OVER (ORDER BY total DESC) AS posicion_rank,
DENSE_RANK() OVER (ORDER BY total DESC) AS posicion_densa
FROM pedidos
WHERE id IN (104, 108, 111, 114, 118)
ORDER BY total DESC, id;| id | total | posicion_rank | posicion_densa |
|---|---|---|---|
| 108 | 249.0 | 1 | 1 |
| 111 | 249.0 | 1 | 1 |
| 114 | 203.9 | 3 | 2 |
| 104 | 179.0 | 4 | 3 |
| 118 | 179.0 | 4 | 3 |
Por qué aparecen 1, 1, 3
- Los dos pedidos de 249 empatan en la primera posición.
RANKcuenta que ya existen dos filas antes del total 203,9 y asigna la posición 3.DENSE_RANKcuenta valores distintos y asigna el nivel 2.- Los pedidos de 179 vuelven a empatar.
Diferencia con ROW_NUMBER
ROW_NUMBER asigna un número diferente a cada fila, incluso cuando los valores empatan. Para obtener un orden estable con ROW_NUMBER suele añadirse un criterio de desempate. Con RANK y DENSE_RANK, ese criterio cambiaría qué filas se consideran empatadas.
Error frecuente
Eliminar los empates sin querer
RANK() OVER (ORDER BY total DESC, id)Como el id es distinto en cada fila, ya no existen filas iguales según el orden completo. La función asignará posiciones diferentes. Utiliza el id solo en el ORDER BY exterior si quieres una presentación estable sin cambiar el empate.
Comprueba lo aprendido
Clasifica salarios por departamento
Devuelve nombre, departamento, salario y una columna nivel_salarial. Usa DENSE_RANK para clasificar de mayor a menor salario dentro de cada departamento.
Solución razonada
SELECT nombre,
departamento,
salario,
DENSE_RANK() OVER (
PARTITION BY departamento
ORDER BY salario DESC
) AS nivel_salarial
FROM empleados
ORDER BY departamento, nivel_salarial, nombre;DENSE_RANK reinicia la clasificación en cada departamento y no deja huecos entre salarios distintos. Si dos empleados empatan, reciben el mismo nivel.
Compatibilidad
RANK y DENSE_RANK están disponibles en los motores modernos que soportan funciones de ventana. La definición de “pares” o filas empatadas depende de las expresiones del ORDER BY de la ventana.
Qué debes recordar
RANKdeja huecos después de los empates.DENSE_RANKno deja huecos.ROW_NUMBERasigna un número único a cada fila.- El orden de la ventana decide qué filas empatan.
Conceptos relacionados
Fuentes técnicas consultadas
Se utilizaron para comprobar las definiciones y el tratamiento de empates. La explicación y los ejemplos son originales.