Udostępnij za pomocą


ROW_NUMBER (Transact-SQL)

Dotyczy:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Punkt końcowy analizy SQL w usłudze Microsoft FabricHurtownia danych w usłudze Microsoft FabricBaza danych SQL w usłudze Microsoft Fabric

Numeruje wynik zbioru wyników. Dokładniej rzecz biorąc, zwraca kolejną liczbę wiersza w ramach partycji zbioru wyników, zaczynając od 1 dla pierwszego wiersza w każdej partycji.

ROW_NUMBER i RANK są podobne. ROW_NUMBER numeruje wszystkie wiersze kolejno (na przykład 1, 2, 3, 4, 5). RANK zapewnia tę samą wartość liczbową dla remisów (na przykład 1, 2, 2, 4, 5).

Uwaga / Notatka

ROW_NUMBER to wartość tymczasowa obliczana podczas wykonywania zapytania. Aby zachować liczby w tabeli, zobacz TOŻSAMOŚĆ Własność i SEKWENCJĘ.

Transact-SQL konwencje składni

Składnia

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

Arguments

PODZIAŁ PRZEZ value_expression
Dzieli zbiór wyników wygenerowany przez klauzulę FROM na partycje, do których zastosowana jest funkcja ROW_NUMBER. value_expression określa kolumnę, według której podzielony jest zbiór wyników. Jeśli PARTITION BY nie jest określona, funkcja traktuje wszystkie wiersze zbioru wyników zapytania jako jedną grupę. Aby uzyskać więcej informacji, zobacz OVER Clause (Transact-SQL).

order_by_clause
Klauzula ORDER BY określa kolejność, w jakiej wiersze są przypisywane jako unikalne ROW_NUMBER w określonej partycji. Jest to wymagane. Aby uzyskać więcej informacji, zobacz OVER Clause (Transact-SQL).

Typy zwracane

bigint

Uwagi ogólne

Nie ma gwarancji, że wiersze zwracane przez zapytanie będą ROW_NUMBER() uporządkowane dokładnie tak samo przy każdym wykonaniu, chyba że spełnione są następujące warunki.

  • Wartości podzielonej kolumny są unikalne.

  • Wartości kolumn ORDER BY są unikalne.

  • Kombinacje wartości kolumny podziału i ORDER BY kolumn są unikalne.

Jeśli kolumny ORDER BY nie są unikalne w wynikach, rozważ użycie RANK() lub DENSE_RANK().

ROW_NUMBER() jest niedeterministyczny. Aby uzyskać więcej informacji, zobacz Funkcje deterministyczne i niedeterministyczne.

Przykłady

A. Proste przykłady

Następujące zapytanie zwraca cztery tabele systemowe w porządku alfabetycznym.

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

Oto zestaw wyników.

nazwa recovery_model_desc
master PROSTY
model PEŁNY
msdb PROSTY
tempdb PROSTY

Aby dodać kolumnę z numerem wiersza przed każdym wierszem, dodaj kolumnę z funkcją ROW_NUMBER , w tym przypadku Row#nazwaną . Musisz przesunąć klauzulę ORDER BY do klauzuli OVER .

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

Oto zestaw wyników.

Szereg# nazwa recovery_model_desc
1 master PROSTY
2 model PEŁNY
3 msdb PROSTY
4 tempdb PROSTY

Klauzula PARTITION BY w kolumnie recovery_model_desc rozpoczyna numerację od nowa, gdy wartość się zmienia 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;

Oto zestaw wyników.

Szereg# nazwa recovery_model_desc
1 model PEŁNY
1 master PROSTY
2 msdb PROSTY
3 tempdb PROSTY

B. Zwracanie numeru wiersza dla sprzedawców

Poniższy przykład oblicza numer wiersza dla sprzedawców w cyklach Adventure Works na podstawie ich rankingu sprzedaży od początku roku.

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;  

Oto zestaw wyników.

  
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. Zwracanie podzbioru wierszy

Poniższy przykład oblicza numery wierszy dla wszystkich wierszy w tabeli SalesOrderHeader w kolejności i OrderDate zwraca tylko wiersze 50 do 60 wartości włącznie.

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. Używając ROW_NUMBER() z PARTITION

Poniższy przykład wykorzystuje PARTITION BY argument do partycjonowania wyniku zapytania zbiorem przez kolumnę TerritoryName. Klauzula ORDER BY określona w klauzuli OVER porządkuje wiersze w każdej partycji według kolumny SalesYTD. Klauzula w zdaniu uporządkowuje ORDER BY cały wynik zapytania określony przez TerritoryName.SELECT

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;  

Oto zestaw wyników.

  
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  

Przykłady: Azure Synapse Analytics and Analytics Platform System (PDW)

E. Zwracanie numeru wiersza dla sprzedawców

Poniższy przykład zwraca wartość ROW_NUMBER przedstawicieli handlowych na podstawie przypisanej im kwoty sprzedażowej.

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

Oto zestaw wyników częściowych.


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. Używając ROW_NUMBER() z PARTITION

Poniższy przykład pokazuje użycie ROW_NUMBER funkcji z argumentem PARTITION BY . Powoduje to, że ROW_NUMBER funkcja numeruje wiersze w każdej partycji.

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

Oto zestaw wyników częściowych.

 
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  

Zobacz też

RANGA (Transact-SQL)
DENSE_RANK (Transact-SQL)
NTILE (Transact-SQL)