ROW_NUMBER (Transact-SQL)
適用於:SQL Server Azure SQL 資料庫 Azure SQL 受控執行個體 Azure Synapse Analytics Analytics Platform System (PDW) Microsoft Fabric 的 SQL 端點分析 Microsoft Fabric 的倉儲
為結果集的輸出編號。 具體來說,傳回結果集分割區內某資料列的序號,序號從 1 開始,每個分割區第一個資料列的序號是 1。
ROW_NUMBER
和 RANK
類似。 ROW_NUMBER
會依序為所有資料列編號 (例如 1、2、3、4、5)。 RANK
為繫結提供相同的數值 (例如 1、2、2、4、5)。
注意
ROW_NUMBER
是查詢在執行時所計算的暫存值。 若要將數字保存在資料表中,請參閱 IDENTITY 屬性和 SEQUENCE。
語法
ROW_NUMBER ( )
OVER ( [ PARTITION BY value_expression , ... [ n ] ] order_by_clause )
引數
PARTITION BY value_expression
將 FROM 子句所產生的結果集分成套用 ROW_NUMBER 函數的分割區。 value_expression 會指定用於分割結果集的資料行。 如未指定 PARTITION BY
,此函數會將查詢結果集的所有資料列視為單一群組。 如需詳細資訊,請參閱 OVER 子句 (Transact-SQL)。
order_by_clause
ORDER BY
子句決定了在指定分割區內,將唯一 ROW_NUMBER
指派給資料列的順序。 此為必要。 如需詳細資訊,請參閱 OVER 子句 (Transact-SQL)。
傳回型別
bigint
一般備註
除非下列條件成立,否則不保證使用 ROW_NUMBER()
之查詢所傳回的資料列一定會在每次執行時依照相同的方式排列。
分割區資料行的值是唯一的。
ORDER BY
資料行的值是唯一的。分割區資料行和
ORDER BY
資料行的值組合是唯一的。
如果結果 ORDER BY
中的數據行不是唯一的,請考慮使用 RANK()
或 DENSE_RANK()
。
ROW_NUMBER()
不具決定性。 如需詳細資訊,請參閱 決定性與非決定性函數。
範例
A. 簡單範例
下列查詢會依字母順序傳回 4 個系統資料表。
SELECT
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5
ORDER BY name ASC;
結果集如下所示。
NAME | recovery_model_desc |
---|---|
master | 簡單 |
model | FULL |
msdb | 簡單 |
tempdb | 簡單 |
若要在每個資料列前面新增資料列號碼資料行,請新增有 ROW_NUMBER
函數的資料行,在此情況下名為 Row#
。 您必須將 ORDER BY
子句移到 OVER
子句。
SELECT
ROW_NUMBER() OVER(ORDER BY name ASC) AS Row#,
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5;
結果集如下所示。
Row# | NAME | recovery_model_desc |
---|---|---|
1 | master | 簡單 |
2 | model | FULL |
3 | msdb | 簡單 |
4 | tempdb | 簡單 |
數據 PARTITION BY
行上的 recovery_model_desc
子句會在值變更時 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;
結果集如下所示。
Row# | NAME | recovery_model_desc |
---|---|---|
1 | model | FULL |
1 | master | 簡單 |
2 | msdb | 簡單 |
3 | tempdb | 簡單 |
B. 傳回銷售人員的資料列編號
下列範例會根據年初至今的銷售業績排名來計算 Adventure Works Cycles 中銷售人員的資料列編號。
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;
結果集如下所示。
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. 傳回資料列的子集
下列範例會計算 SalesOrderHeader
資料表中所有資料列的編號,並以 OrderDate
順序排列,然後只傳回包含 50
至 60
的資料列。
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. 並用 PARTITION 與 ROW_NUMBER()
下列範例使用 PARTITION BY
引數依據資料行 TerritoryName
分割查詢結果集。 ORDER BY
子句中指定的 OVER
子句會依資料行 SalesYTD
排列每個分割區的資料列。 ORDER BY
陳述式中的 SELECT
子句會依照 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;
結果集如下所示。
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
範例:Azure Synapse Analytics 和 Analytics Platform System (PDW)
E. 傳回銷售人員的資料列編號
下列範例會根據銷售代表被指派的銷售配額,傳回銷售代表的 ROW_NUMBER
。
-- 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;
以下為部分結果集。
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. 並用 PARTITION 與 ROW_NUMBER()
下列範例顯示如何搭配 ROW_NUMBER
引數使用 PARTITION BY
函數。 這會導致 ROW_NUMBER
函數為每個分割區中的資料列編號。
-- 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;
以下為部分結果集。
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
另請參閱
RANK (Transact-SQL)
DENSE_RANK (Transact-SQL)
NTILE (Transact-SQL)