Volver a la página principal
viernes 27 septiembre 2024
84

Cómo numerar filas con ROW_NUMBER en SQL Server

¿Qué es 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:

  • Crear índices secuenciales en consultas.
  • Paginación de resultados en aplicaciones.
  • Seleccionar o eliminar filas duplicadas.
  • Realizar operaciones de ranking sin empates.

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.

Sintaxis de 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.

Ejemplos de uso de ROW_NUMBER

Numerar filas de un conjunto completo

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.

Numerar filas dentro de grupos usando 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.

Seleccionar las primeras 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.

Eliminar filas duplicadas de una tabla

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.

Consideraciones importantes

  • Si el conjunto de resultados no tiene un criterio de orden (ORDER BY), ROW_NUMBER asignará los números de fila arbitrariamente.
  • La numeración siempre comienza en 1 para cada conjunto o partición.
  • A diferencia de RANK y DENSE_RANK, ROW_NUMBER no permite empates en la numeración.

Referencia oficial

Para más información sobre ROW_NUMBER, consulta la documentación oficial de Microsoft.

Compartir:
Creado por:
Author photo

Jorge García

Fullstack developer