ROW_NUMBER (Transact-SQL)
Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Punto de conexión de análisis SQL en Microsoft Fabric Almacenamiento en Microsoft Fabric
Enumera los resultados de un conjunto de resultados. Concretamente, devuelve el número secuencial de una fila dentro de una partición de un conjunto de resultados, empezando por 1 para la primera fila de cada partición.
ROW_NUMBER
y RANK
son similares. ROW_NUMBER
enumera todas las filas secuencialmente (por ejemplo 1, 2, 3, 4, 5). RANK
proporciona el mismo valor numérico para valores equivalentes (por ejemplo 1, 2, 2, 4, 5).
Nota
ROW_NUMBER
es un valor temporal que se calcula cuando se ejecuta la consulta. Para conservar los números de una tabla, vea Propiedad IDENTITY y SEQUENCE.
Convenciones de sintaxis de Transact-SQL
Sintaxis
ROW_NUMBER ( )
OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
Argumentos
PARTITION BY value_expression
Divide el conjunto de resultados generado por la cláusula FROM en particiones a las que se aplica la función ROW_NUMBER. value_expression especifica la columna a partir de la cual se particiona el conjunto de resultados. Si no se especifica PARTITION BY
, la función trata todas las filas del conjunto de resultados de la consulta como un único grupo. Para más información, vea Cláusula OVER (Transact-SQL).
order_by_clause
La cláusula ORDER BY
determina la secuencia en la que se asigna a las filas el ROW_NUMBER
único correspondiente en una partición especificada. Es obligatorio. Para más información, vea Cláusula OVER (Transact-SQL).
Tipos de valor devuelto
bigint
Notas generales
No hay ninguna garantía de que las filas devueltas por una consulta con al usar ROW_NUMBER()
se ordenen exactamente igual con cada ejecución a menos que se cumplan estas condiciones:
Los valores de la columna de la partición sean únicos.
Los valores de las columnas
ORDER BY
sean únicos.Las combinaciones de los valores de la columna de la partición y las columnas
ORDER BY
sean únicas.
Si las ORDER BY
columnas no son únicas dentro de los resultados, considere la posibilidad de usar RANK()
o DENSE_RANK()
.
ROW_NUMBER()
sea no determinista. Para obtener más información, consulte Deterministic and Nondeterministic Functions.
Ejemplos
A. Ejemplos sencillos
La siguiente consulta devuelve las cuatro tablas del sistema en orden alfabético.
SELECT
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5
ORDER BY name ASC;
Este es el conjunto de resultados.
nombre | recovery_model_desc |
---|---|
maestro | SIMPLE |
model | FULL |
msdb | SIMPLE |
tempdb | SIMPLE |
Para agregar una columna de número de fila delante de cada fila, agregue una columna con la función ROW_NUMBER
, en este caso denominada Row#
. Debe mover la cláusula ORDER BY
hasta la cláusula OVER
.
SELECT
ROW_NUMBER() OVER(ORDER BY name ASC) AS Row#,
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5;
Este es el conjunto de resultados.
Row# | name | recovery_model_desc |
---|---|---|
1 | maestro | SIMPLE |
2 | model | FULL |
3 | msdb | SIMPLE |
4 | tempdb | SIMPLE |
La PARTITION BY
cláusula de la recovery_model_desc
columna reinicia la numeración cuando cambia el recovery_model_desc
valor.
SELECT
ROW_NUMBER() OVER(PARTITION BY recovery_model_desc ORDER BY name ASC)
AS Row#,
name, recovery_model_desc
FROM sys.databases WHERE database_id < 5;
Este es el conjunto de resultados.
Row# | name | recovery_model_desc |
---|---|---|
1 | model | FULL |
1 | maestro | SIMPLE |
2 | msdb | SIMPLE |
3 | tempdb | SIMPLE |
B. Devolver el número de fila de vendedor
En el ejemplo siguiente se calcula un número de fila para los vendedores de Adventure Works Cycles según la categoría de ventas anuales hasta la fecha.
USE AdventureWorks2022;
GO
SELECT ROW_NUMBER() OVER(ORDER BY SalesYTD DESC) AS Row,
FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD"
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0;
Este es el conjunto de resultados.
Row FirstName LastName SalesYTD
--- ----------- ---------------------- -----------------
1 Linda Mitchell 4251368.54
2 Jae Pak 4116871.22
3 Michael Blythe 3763178.17
4 Jillian Carson 3189418.36
5 Ranjit Varkey Chudukatil 3121616.32
6 José Saraiva 2604540.71
7 Shu Ito 2458535.61
8 Tsvi Reiter 2315185.61
9 Rachel Valdez 1827066.71
10 Tete Mensa-Annan 1576562.19
11 David Campbell 1573012.93
12 Garrett Vargas 1453719.46
13 Lynn Tsoflias 1421810.92
14 Pamela Ansman-Wolfe 1352577.13
C. Devolver un subconjunto de filas
En el ejemplo siguiente se calculan los números de fila para todas las filas de la tabla SalesOrderHeader
en el orden de OrderDate
y solo se devuelven las filas 50
a 60
inclusive.
USE AdventureWorks2022;
GO
WITH OrderedOrders AS
(
SELECT SalesOrderID, OrderDate,
ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
FROM Sales.SalesOrderHeader
)
SELECT SalesOrderID, OrderDate, RowNumber
FROM OrderedOrders
WHERE RowNumber BETWEEN 50 AND 60;
D. Usar ROW_NUMBER() con PARTITION
En el ejemplo siguiente se usa el argumento PARTITION BY
para crear particiones del conjunto de resultados de la consulta por la columna TerritoryName
. La cláusula ORDER BY
especificada en la cláusula OVER
ordena las filas de cada partición por la columna SalesYTD
. La cláusula ORDER BY
de la instrucción SELECT
ordena todo el conjunto de resultados de la consulta por TerritoryName
.
USE AdventureWorks2022;
GO
SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1) AS SalesYTD,
ROW_NUMBER() OVER(PARTITION BY TerritoryName ORDER BY SalesYTD DESC)
AS Row
FROM Sales.vSalesPerson
WHERE TerritoryName IS NOT NULL AND SalesYTD <> 0
ORDER BY TerritoryName;
Este es el conjunto de resultados.
FirstName LastName TerritoryName SalesYTD Row
--------- -------------------- ------------------ ------------ ---
Lynn Tsoflias Australia 1421810.92 1
José Saraiva Canada 2604540.71 1
Garrett Vargas Canada 1453719.46 2
Jillian Carson Central 3189418.36 1
Ranjit Varkey Chudukatil France 3121616.32 1
Rachel Valdez Germany 1827066.71 1
Michael Blythe Northeast 3763178.17 1
Tete Mensa-Annan Northwest 1576562.19 1
David Campbell Northwest 1573012.93 2
Pamela Ansman-Wolfe Northwest 1352577.13 3
Tsvi Reiter Southeast 2315185.61 1
Linda Mitchell Southwest 4251368.54 1
Shu Ito Southwest 2458535.61 2
Jae Pak United Kingdom 4116871.22 1
Ejemplos: Azure Synapse Analytics y Sistema de la plataforma de análisis (PDW)
E. Devolver el número de fila de vendedor
En este ejemplo se devuelve ROW_NUMBER
para los representantes de ventas en función de su cuota de ventas asignada.
-- Uses AdventureWorks
SELECT ROW_NUMBER() OVER(ORDER BY SUM(SalesAmountQuota) DESC)
AS RowNumber,
FirstName, LastName,
CONVERT(varchar(13), SUM(SalesAmountQuota),1) AS SalesQuota
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS sq
ON e.EmployeeKey = sq.EmployeeKey
WHERE e.SalesPersonFlag = 1
GROUP BY LastName, FirstName;
A continuación se muestra un conjunto parcial de resultados.
RowNumber FirstName LastName SalesQuota
--------- --------- ------------------ -------------
1 Jillian Carson 12,198,000.00
2 Linda Mitchell 11,786,000.00
3 Michael Blythe 11,162,000.00
4 Jae Pak 10,514,000.00
F. Usar ROW_NUMBER() con PARTITION
El ejemplo siguiente muestra cómo utilizar la función ROW_NUMBER
con el argumento PARTITION BY
. Esto provoca que la función ROW_NUMBER
enumere las filas de cada partición.
-- Uses AdventureWorks
SELECT ROW_NUMBER() OVER(PARTITION BY SalesTerritoryKey
ORDER BY SUM(SalesAmountQuota) DESC) AS RowNumber,
LastName, SalesTerritoryKey AS Territory,
CONVERT(varchar(13), SUM(SalesAmountQuota),1) AS SalesQuota
FROM dbo.DimEmployee AS e
INNER JOIN dbo.FactSalesQuota AS sq
ON e.EmployeeKey = sq.EmployeeKey
WHERE e.SalesPersonFlag = 1
GROUP BY LastName, FirstName, SalesTerritoryKey;
A continuación se muestra un conjunto parcial de resultados.
RowNumber LastName Territory SalesQuota
--------- ------------------ --------- -------------
1 Campbell 1 4,025,000.00
2 Ansman-Wolfe 1 3,551,000.00
3 Mensa-Annan 1 2,275,000.00
1 Blythe 2 11,162,000.00
1 Carson 3 12,198,000.00
1 Mitchell 4 11,786,000.00
2 Ito 4 7,804,000.00
Consulte también
RANK (Transact-SQL)
DENSE_RANK (Transact-SQL)
NTILE (Transact-SQL)