ROW_NUMBER(Transact-SQL)
적용 대상: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System(PDW) Microsoft Fabric의 SQL 분석 엔드포인트 Microsoft Fabric의 웨어하우스
결과 집합의 출력 번호를 지정합니다. 보다 구체적으로는, 결과 집합 파티션 내의 행 일련 번호를 반환합니다. 각 파티션의 첫 번째 행은 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()
는 비결정적입니다. 자세한 내용은 Deterministic and Nondeterministic Functions을 참조하세요.
예제
A. 간단한 예제
다음 쿼리는 알파벳 순서로 4개의 시스템 테이블을 반환합니다.
SELECT
name, recovery_model_desc
FROM sys.databases
WHERE database_id < 5
ORDER BY name ASC;
결과 집합은 다음과 같습니다.
name | recovery_model_desc |
---|---|
master | SIMPLE |
model | FULL |
msdb | SIMPLE |
tempdb | SIMPLE |
각 행 앞에 행 번호 열을 추가하려면 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 | SIMPLE |
2 | model | FULL |
3 | msdb | SIMPLE |
4 | tempdb | SIMPLE |
열의 recovery_model_desc
절은 PARTITION BY
값이 변경되면 번호 매기기를 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 | SIMPLE |
2 | msdb | SIMPLE |
3 | tempdb | SIMPLE |
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 및 분석 플랫폼 시스템(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)