ROW_NUMBER (Transact-SQL)

Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Punto de conexión de análisis SQL en Microsoft FabricAlmacenamiento 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 )  

Nota:

Para ver la sintaxis de Transact-SQL para SQL Server 2014 (12.x) y versiones anteriores, consulte Versiones anteriores de la documentación.

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:

  1. Los valores de la columna de la partición sean únicos.

  2. Los valores de las columnas ORDER BY sean únicos.

  3. Las combinaciones de los valores de la columna de la partición y las columnas ORDER BY sean únicas.

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;

El conjunto de resultados es el siguiente:

name 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;

El conjunto de resultados es el siguiente:

Row# name recovery_model_desc
1 maestro SIMPLE
2 model FULL
3 msdb SIMPLE
4 tempdb SIMPLE

Al agregar una cláusula PARTITION BY en la columna recovery_model_desc, se reiniciará la numeración cuando cambie el valor recovery_model_desc.

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;

El conjunto de resultados es el siguiente:

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;  

El conjunto de resultados es el siguiente:

  
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;  

El conjunto de resultados es el siguiente:

  
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)