De ventanaestándar SQL

ROW_NUMBER

Numera las filas 1, 2, 3… en un orden dado: en todo el resultado o dentro de cada grupo.

Sintaxis

ROW_NUMBER() OVER (ORDER BY <criterio de orden>)
ROW_NUMBER() OVER (PARTITION BY <grupo> ORDER BY <criterio de orden>)

Una función de ventana: no reduce el número de filas, sino que añade a cada una su número. PARTITION BY reinicia la numeración en cada grupo; así se construye «el top N de cada categoría».

Datos para los ejemplos

employees

namedepartmentsalarybonusphone
Emmabackend1200300+44 7700 900123
Liambackend1000NULLNULL
Oliviafrontend1350150+44 7700 900456
Noahfrontend950NULL+44 7700 900789
Sophiadesign1200200NULL

Estas tablas ya están creadas en el entorno de pruebas y los ejemplos de abajo las usan. ¿Quieres repetirlo en tu propia base de datos? Copia el SQL.

Puestos por salario
SELECT name, salary,
ROW_NUMBER() OVER (ORDER BY salary DESC) AS place
FROM employees;
namesalaryplace
Olivia13501
Emma12002
Sophia12003
Liam10004
Noah9505

Emma y Sophia ganan lo mismo, pero reciben números distintos: el azar decide quién es segunda. Más detalles en «Ten en cuenta».

La numeración se reinicia en cada departamento
SELECT name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS place
FROM employees;
namedepartmentsalaryplace
Emmabackend12001
Liambackend10002
Sophiadesign12001
Oliviafrontend13501
Noahfrontend9502
El salario más alto de cada departamentoAvanzado
SELECT name, department, salary
FROM (
SELECT name, department, salary,
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS place
FROM employees
) ranked
WHERE place = 1;
namedepartmentsalary
Emmabackend1200
Sophiadesign1200
Oliviafrontend1350

El número no se puede usar en el WHERE de la misma consulta, así que primero numeramos en una subconsulta y filtramos fuera.

Ten en cuenta

Los valores iguales reciben números distintos igualmente, y cuál va primero es cuestión de azar. Añade a ORDER BY un campo único, como id, para que el orden sea estable.

Si los valores iguales deben compartir puesto, usa RANK o DENSE_RANK.

Funciones relacionadas

Más detalles en el curso