Partilhar via


ROW_NUMBER (Transact-SQL)

Aplica-se a:SQL ServerBase de Dados SQL do AzureInstância Gerida do Azure SQLAzure Synapse AnalyticsSistema de Plataforma de Análise (PDW)Ponto de Extremidade de Análise SQL no Microsoft FabricArmazém no Microsoft FabricBase de Dados SQL no Microsoft Fabric

Numera a saída de um conjunto de resultados. Mais especificamente, devolve o número sequencial de uma linha dentro de uma partição de um conjunto de resultados, começando em 1 para a primeira linha de cada partição.

ROW_NUMBER e RANK são semelhantes. ROW_NUMBER numera todas as linhas sequencialmente (por exemplo, 1, 2, 3, 4, 5). RANK fornece o mesmo valor numérico para empates (por exemplo, 1, 2, 2, 4, 5).

Observação

ROW_NUMBER é um valor temporário calculado quando a consulta é executada. Para persistir números numa tabela, veja IDENTITY Property e SEQUENCE.

Transact-SQL convenções de sintaxe

Sintaxe

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

Arguments

PARTIÇÃO POR value_expression
Divide o conjunto de resultados produzido pela cláusula FROM em partições às quais a função ROW_NUMBER é aplicada. value_expression especifica a coluna pela qual o conjunto de resultados é particionado. Se PARTITION BY não for especificado, a função trata todas as linhas do conjunto de resultados da consulta como um único grupo. Para obter mais informações, consulte Cláusula OVER (Transact-SQL).

order_by_clause
A ORDER BY cláusula determina a sequência em que as linhas são atribuídas como únicas ROW_NUMBER dentro de uma partição especificada. É obrigatório. Para obter mais informações, consulte Cláusula OVER (Transact-SQL).

Tipos de devolução

bigint

Observações gerais

Não há garantia de que as linhas devolvidas por uma consulta usando ROW_NUMBER() serão ordenadas exatamente da mesma forma em cada execução, a menos que as seguintes condições sejam verdadeiras.

  • Os valores da coluna particionada são únicos.

  • Os valores das ORDER BY colunas são únicos.

  • Combinações de valores da coluna e ORDER BY colunas da partição são únicas.

Se as ORDER BY colunas não forem únicas nos resultados, considere usar RANK() ou DENSE_RANK().

ROW_NUMBER() é não determinística. Para mais informações, consulte Funções Determinísticas e Não Determinísticas.

Examples

A. Exemplos simples

A consulta seguinte devolve as quatro tabelas do sistema por ordem alfabética.

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

Aqui está o conjunto de resultados.

nome recovery_model_desc
master SIMPLES
modelo COMPLETO
msdb SIMPLES
tempdb SIMPLES

Para adicionar uma coluna de número de linha à frente de cada linha, adicione uma coluna com a ROW_NUMBER função, neste caso chamada Row#. Tem de avançar a ORDER BY cláusula para a OVER cláusula.

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.

Row# nome recovery_model_desc
1 master SIMPLES
2 modelo COMPLETO
3 msdb SIMPLES
4 tempdb SIMPLES

A PARTITION BY cláusula na recovery_model_desc coluna reinicia a numeração quando o recovery_model_desc valor muda.

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.

Row# nome recovery_model_desc
1 modelo COMPLETO
1 master SIMPLES
2 msdb SIMPLES
3 tempdb SIMPLES

B. Devolver o número da fila aos vendedores

O exemplo seguinte calcula um número de linha para os vendedores na Adventure Works Cycles com base na sua classificação de vendas acumulada no ano.

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;  

Aqui está o 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 um subconjunto de linhas

O exemplo seguinte calcula os números de linhas para todas as SalesOrderHeader linhas da tabela na ordem do OrderDate e devolve apenas as 50 linhas 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() com PARTITION

O exemplo seguinte usa o PARTITION BY argumento para particionar o conjunto de resultados da consulta pela coluna TerritoryName. A ORDER BY cláusula especificada na OVER cláusula ordena as linhas em cada partição pela coluna SalesYTD. A ORDER BY cláusula na SELECT sentença ordena todo o resultado da 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;  

Aqui está o 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  

Exemplos: Azure Synapse Analytics and Analytics Platform System (PDW)

E. Devolver o número da fila aos vendedores

O exemplo seguinte devolve o ROW_NUMBER para representantes de vendas com base na sua quota de vendas atribuída.

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

Aqui está um conjunto de resultados parcial.


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() com PARTITION

O exemplo seguinte mostra o uso da ROW_NUMBER função com o PARTITION BY argumento. Isto faz com que a ROW_NUMBER função numere as linhas em cada partição.

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

Aqui está um conjunto de resultados parcial.

 
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  

Ver também

POSIÇÃO (Transact-SQL)
DENSE_RANK (Transact-SQL)
NTILE (Transact-SQL)