ROW_NUMBER (Transact-SQL)
Возвращает последовательный номер строки в секции результирующего набора, где 1 соответствует первой строке в каждой из секций.
Применимо для следующих объектов: SQL Server (SQL Server 2008 по текущую версию), База данных SQL Windows Azure (с первоначального выпуска по текущий выпуск). |
Синтаксические обозначения в Transact-SQL
Синтаксис
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 являются уникальными.
Функция ROW_NUMBER() не детерминирована. Дополнительные сведения см. в разделе Детерминированные и недетерминированные функции.
Примеры
А.Возврат номера строки для salespeople
В следующем примере показан расчет номера строки для salespeople в Компания Adventure Works Cycles, выполняемый на основе ранжирования продаж за текущий год.
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;
Ниже приводится результирующий набор.
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
Б.Возврат подмножества строк
В следующем примере показан расчет номеров всех строк в таблице SalesOrderHeader в порядке OrderDate с последующим возвращением строк с номерами от 50 до 60 включительно.
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;
В.Использование ROW_NUMBER() с PARTITION
В следующем примере аргумент PARTITION BY используется для секционирования результирующего набора запроса по столбцу TerritoryName. Предложение ORDER BY, указанное в предложении OVER, упорядочивает строки каждой секции по столбцу SalesYTD. Предложение ORDER BY в инструкции SELECT упорядочивает полный результирующий набор запроса по TerritoryName.
USE AdventureWorks2012;
GO
SELECT FirstName, LastName, TerritoryName, ROUND(SalesYTD,2,1),
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