ROW_NUMBER (Transact-SQL)ROW_NUMBER (Transact-SQL)

ESTE TÓPICO APLICA-SE A: simSQL Server (a partir de 2008)simBanco de Dados SQL do Microsoft AzuresimAzure SQL Data Warehouse simParallel Data Warehouse THIS TOPIC APPLIES TO: yesSQL Server (starting with 2008)yesAzure SQL DatabaseyesAzure SQL Data Warehouse yesParallel Data Warehouse

Numera a saída de um conjunto de resultados.Numbers the output of a result set. Mais especificamente, retorna o número sequencial de uma linha em uma partição de um conjunto de resultados, começando em 1 na primeira linha de cada partição.More specifically, returns the sequential number of a row within a partition of a result set, starting at 1 for the first row in each partition.

ROW_NUMBER e RANK são semelhantes.ROW_NUMBER and RANK are similar. ROW_NUMBER numera todas as linhas em sequência (por exemplo 1, 2, 3, 4, 5).ROW_NUMBER numbers all rows sequentially (for example 1, 2, 3, 4, 5). RANK fornece o mesmo valor numérico para empates (por exemplo 1, 2, 2, 4, 5).RANK provides the same numeric value for ties (for example 1, 2, 2, 4, 5).

Observação

ROW_NUMBER é um valor temporário calculado quando a consulta é executada.ROW_NUMBER is a temporary value calculated when the query is run. Para persistir números em uma tabela, consulte Propriedade IDENTITY e SEQUENCE.To persist numbers in a table, see IDENTITY Property and SEQUENCE.

Ícone de link do tópico Convenções de sintaxe de Transact-SQLTopic link icon Transact-SQL Syntax Conventions

SintaxeSyntax

ROW_NUMBER ( )   
    OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )  

ArgumentosArguments

PARTITION BY value_expressionPARTITION BY value_expression
Divide o conjunto de resultados produzido pela cláusula FROM nas partições às quais a função ROW_NUMBER é aplicada.Divides the result set produced by the FROM clause into partitions to which the ROW_NUMBER function is applied. value_expression especifica a coluna pela qual o conjunto de resultados é particionado.value_expression specifies the column by which the result set is partitioned. Se PARTITION BY não for especificado, a função tratará todas as linhas do conjunto de resultados da consulta como um único grupo.If PARTITION BY is not specified, the function treats all rows of the query result set as a single group. Para obter mais informações, consulte Cláusula OVER (Transact-SQL).For more information, see OVER Clause (Transact-SQL).

order_by_clauseorder_by_clause
A cláusula ORDER BY determina a sequência na qual as linhas recebem seu ROW_NUMBER exclusivo em uma partição especificada.The ORDER BY clause determines the sequence in which the rows are assigned their unique ROW_NUMBER within a specified partition. É obrigatório.It is required. Para obter mais informações, consulte Cláusula OVER (Transact-SQL).For more information, see OVER Clause (Transact-SQL).

Tipos de retornoReturn Types

bigintbigint

Comentários geraisGeneral Remarks

Não há nenhuma garantia de que as linhas retornadas por uma consulta que usa ROW_NUMBER() serão ordenadas exatamente da mesma maneira com cada execução, a menos que as condições a seguir sejam verdadeiras.There is no guarantee that the rows returned by a query using ROW_NUMBER() will be ordered exactly the same with each execution unless the following conditions are true.

  1. Os valores da coluna particionada sejam exclusivos.Values of the partitioned column are unique.

  2. Os valores das ORDER BY colunas são exclusivos.Values of the ORDER BY columns are unique.

  3. As combinações de valores da coluna de partição e colunas ORDER BY são exclusivas.Combinations of values of the partition column and ORDER BY columns are unique.

    ROW_NUMBER() é não determinístico.ROW_NUMBER() is nondeterministic. Para obter mais informações, veja Funções determinísticas e não determinísticas.For more information, see Deterministic and Nondeterministic Functions.

ExemplosExamples

A.A. Exemplos simplesSimple examples

A consulta a seguir retorna as quatro tabelas do sistema em ordem alfabética.The following query returns the four system tables in alphabetic order.

SELECT 
  name, recovery_model_desc
FROM sys.databases 
WHERE database_id < 5
ORDER BY name ASC;

Aqui está o conjunto de resultados.Here is the result set.

NAMEname recovery_model_descrecovery_model_desc
mastermaster SIMPLESIMPLE
modelomodel FULLFULL
msdbmsdb SIMPLESIMPLE
tempdbtempdb SIMPLESIMPLE

Para adicionar uma coluna de número de linha na frente de cada linha, adicione uma coluna com a função ROW_NUMBER, nesse caso, chamada Row#.To add a row number column in front of each row, add a column with the ROW_NUMBER function, in this case named Row#. É necessário mover a cláusula ORDER BY até a cláusula OVER.You must move the ORDER BY clause up to the OVER clause.

SELECT 
  ROW_NUMBER() OVER(ORDER BY name ASC) AS Row#,
  name, recovery_model_desc
FROM sys.databases 
WHERE database_id < 5;

Aqui está o conjunto de resultados.Here is the result set.

Row#Row# NAMEname recovery_model_descrecovery_model_desc
11 mastermaster SIMPLESIMPLE
22 modelomodel FULLFULL
33 msdbmsdb SIMPLESIMPLE
44 tempdbtempdb SIMPLESIMPLE

A adição de uma cláusula PARTITION BY à coluna recovery_model_desc reiniciará a numeração quando o valor recovery_model_desc for alterado.Adding a PARTITION BY clause on the recovery_model_desc column, will restart the numbering when the recovery_model_desc value changes.

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;

Aqui está o conjunto de resultados.Here is the result set.

Row#Row# NAMEname recovery_model_descrecovery_model_desc
11 modelomodel FULLFULL
11 mastermaster SIMPLESIMPLE
22 msdbmsdb SIMPLESIMPLE
33 tempdbtempdb SIMPLESIMPLE

B.B. Retornando o número de linha para vendedoresReturning the row number for salespeople

O exemplo a seguir calcula um número de linha para os vendedores da Ciclos da Adventure WorksAdventure Works Cycles com base em sua classificação de vendas no ano até a data.The following example calculates a row number for the salespeople in Ciclos da Adventure WorksAdventure Works Cycles based on their year-to-date sales ranking.

USE AdventureWorks2012;   
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;  

Aqui está o conjunto de resultados.Here is the result set.


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.C. Retornando um subconjunto de linhasReturning a subset of rows

O exemplo a seguir calcula números de linha para todas as linhas da tabela SalesOrderHeader na ordem de OrderDate e retorna somente as linhas de 50 a 60.The following example calculates row numbers for all rows in the SalesOrderHeader table in the order of the OrderDate and returns only rows 50 to 60 inclusive.

USE AdventureWorks2012;  
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.D. Usando ROW_NUMBER () com PARTITIONUsing ROW_NUMBER() with PARTITION

O exemplo a seguir usa o argumento PARTITION BY para particionar o conjunto de resultados da consulta pela coluna TerritoryName.The following example uses the PARTITION BY argument to partition the query result set by the column TerritoryName. A cláusula ORDER BY especificada na cláusula OVER ordena as linhas em cada partição pela coluna SalesYTD.The ORDER BY clause specified in the OVER clause orders the rows in each partition by the column SalesYTD. A cláusula ORDER BY na instrução SELECT ordena o conjunto de resultados inteiro da consulta por TerritoryName.The ORDER BY clause in the SELECT statement orders the entire query result set by TerritoryName.

USE AdventureWorks2012;  
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;  

Aqui está o conjunto de resultados.Here is the result set.


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  

Exemplos: Azure SQL Data WarehouseAzure SQL Data Warehouse e Parallel Data WarehouseParallel Data WarehouseExamples: Azure SQL Data WarehouseAzure SQL Data Warehouse and Parallel Data WarehouseParallel Data Warehouse

E.E. Retornando o número de linha para vendedoresReturning the row number for salespeople

O exemplo a seguir retorna o ROW_NUMBER de representantes de vendas com base em suas cotas de vendas atribuídas.The following example returns the ROW_NUMBER for sales representatives based on their assigned sales quota.

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

Este é um conjunto de resultados parcial.Here is a partial result set.


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.F. Usando ROW_NUMBER () com PARTITIONUsing ROW_NUMBER() with PARTITION

O exemplo a seguir mostra o uso da função ROW_NUMBER com o argumento PARTITION BY.The following example shows using the ROW_NUMBER function with the PARTITION BY argument. Isso faz com que a função ROW_NUMBER numere as linhas em cada partição.This causes the ROW_NUMBER function to number the rows in each partition.

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

Este é um conjunto de resultados parcial.Here is a partial result set.


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 TambémSee Also

RANK (Transact-SQL) RANK (Transact-SQL)
DENSE_RANK (Transact-SQL) DENSE_RANK (Transact-SQL)
NTILE (Transact-SQL)NTILE (Transact-SQL)