ROW_NUMBER y para qué se usa?
ROW_NUMBER es una función de ventana que genera un número de fila único para cada fila dentro de una partición o conjunto de resultados. La numeración se basa en un criterio de ordenación especificado en la cláusula ORDER BY dentro de OVER. Esta función es ideal para:
A diferencia de otras funciones de ranking como RANK o DENSE_RANK, ROW_NUMBER garantiza que cada fila tenga un número único, independientemente de si los valores de la columna de orden son iguales.
ROW_NUMBER
ROW_NUMBER() OVER ( [PARTITION BY column1, column2, ...] ORDER BY column_name [ASC|DESC] )
PARTITION BY: (Opcional) Divide el conjunto de resultados en grupos y reinicia la numeración para cada partición.
ORDER BY: Especifica cómo se ordenan las filas dentro de cada partición (o del conjunto completo) para generar el número de fila.
ROW_NUMBER
Supongamos que tienes una tabla llamada Empleados con las columnas EmpleadoID y Salario. Para asignar un número de fila único a cada empleado en función del salario:
SELECT EmpleadoID, Salario,
ROW_NUMBER() OVER (ORDER BY Salario DESC) AS NumeroFila
FROM Empleados;
Resultado:
EmpleadoID | Salario | NumeroFila
-----------|---------|-----------
1 | 5000 | 1
3 | 4500 | 2
2 | 4000 | 3
4 | 3500 | 4
En este ejemplo, ROW_NUMBER asigna un número de fila basado en el orden descendente de Salario.
PARTITION BY
Si quieres numerar empleados dentro de cada departamento, puedes usar PARTITION BY:
SELECT Departamento, EmpleadoID, Salario,
ROW_NUMBER() OVER (PARTITION BY Departamento ORDER BY Salario DESC) AS NumeroFila
FROM Empleados;
Resultado:
Departamento | EmpleadoID | Salario | NumeroFila
-------------|------------|---------|-----------
Ventas | 1 | 5000 | 1
Ventas | 3 | 4500 | 2
Soporte | 2 | 4000 | 1
Soporte | 4 | 3500 | 2
El número de fila se reinicia para cada valor único de Departamento, generando numeraciones independientes para cada grupo.
N filas de cada grupo
Puedes usar ROW_NUMBER para seleccionar las primeras filas de cada categoría. Por ejemplo, si deseas encontrar los 2 empleados mejor pagados de cada departamento:
WITH EmpleadosOrdenados AS (
SELECT Departamento, EmpleadoID, Salario,
ROW_NUMBER() OVER (PARTITION BY Departamento ORDER BY Salario DESC) AS NumeroFila
FROM Empleados
)
SELECT * FROM EmpleadosOrdenados WHERE NumeroFila <= 2;
Resultado:
Departamento | EmpleadoID | Salario | NumeroFila
-------------|------------|---------|-----------
Ventas | 1 | 5000 | 1
Ventas | 3 | 4500 | 2
Soporte | 2 | 4000 | 1
Soporte | 4 | 3500 | 2
El uso de WITH y la subconsulta permite filtrar las primeras 2 filas de cada departamento.
Puedes usar ROW_NUMBER para identificar y eliminar duplicados en una tabla. Por ejemplo, si tienes una tabla Clientes con filas duplicadas basadas en el nombre:
WITH Duplicados AS (
SELECT ClienteID, Nombre,
ROW_NUMBER() OVER (PARTITION BY Nombre ORDER BY ClienteID) AS NumeroFila
FROM Clientes
)
DELETE FROM Duplicados WHERE NumeroFila > 1;
Este comando elimina todas las filas duplicadas, dejando solo la primera ocurrencia de cada nombre.
ORDER BY), ROW_NUMBER asignará los números de fila arbitrariamente.
RANK y DENSE_RANK, ROW_NUMBER no permite empates en la numeración.
Para más información sobre ROW_NUMBER, consulta la documentación oficial de Microsoft.
Jorge García
Fullstack developer