РАНГ (Transact-SQL)

Относится к:SQL ServerБаза данных SQL AzureУправляемый экземпляр SQL AzureAzure Synapse AnalyticsSQL аналитическая конечная точка в Microsoft FabricХранилище в Microsoft FabricSQL база данных в Microsoft Fabric

Возвращает ранг каждой строки в секции результирующего набора. Ранг строки вычисляется как единица плюс количество рангов, находящихся до этой строки.

Функции ROW_NUMBER и RANK похожи. ROW_NUMBER нумерует все строки по порядку (например, 1, 2, 3, 4, 5). RANK назначает одинаковое числовое значение строкам, претендующим на один ранг (например, 1, 2, 2, 4, 5).

Примечание.

RANK — это временное значение, вычисляемое во время выполнения запроса. Чтобы сохранить числа в таблице, см. IDENTITY (Свойство) и CREATE SEQUENCE.

Соглашения о синтаксисе Transact-SQL

Синтаксис

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )

Аргументы

OVER ( [ partition_by_clause ] order_by_clause )

partition_by_clause делит множество результатов, полученное предложениемFROM, на разбиения, к которым применяется функция. Если этот параметр не указан, функция обрабатывает все строки результирующего набора запроса как отдельные группы.

order_by_clause определяет порядок данных перед применением функции. Аргумент order_by_clause является обязательным. <rows or range clause> Пункт OVER of нельзя задать для функцииRANK. Дополнительные сведения см. в предложении SELECT - OVER.

Типы возвращаемых данных

bigint

Замечания

Если на один ранг претендуют две и более строки, все они получат одинаковый ранг. Например, если два ведущих продавца имеют одинаковую SalesYTD ценность, они оба попадают в одинаковый ранг. Продавец с следующим по высоте SalesYTD занимает третье место, потому что есть две строки выше. Поэтому RANK функция не всегда возвращает последовательные целые числа.

Порядок сортировки, используемый для всего запроса, определяет порядок, в котором строки будут появляться в результирующем наборе.

Функция RANK не детерминирована. Дополнительные сведения см. в разделе детерминированные и недетерминированные функции.

Для рекомендаций по настройке производительности функций окна см. OVER() Вопросы производительности.

Примеры

Образцы кода в этой статье используют AdventureWorks2025, AdventureWorksDW2025или AdventureWorksLT2025 примерную базу данных, которую можно скачать из репозитория GitHub Azure Data Data SQL Samples Repository (Сэмпл SQL).

А. Ранговые строки внутри разбиения

Следующий пример ранжирует продукты по количеству в указанных местоположениях в описи. Результирующий набор секционируется по LocationID и логически сортируется по Quantity. В отделении 3 товары 494 и 495 имеют одинаковое количество товаров. Поскольку они равны, они оба в первом месте.

USE AdventureWorks2025;
GO

SELECT i.ProductID,
       p.Name,
       i.LocationID,
       i.Quantity,
       RANK() OVER (PARTITION BY i.LocationID ORDER BY i.Quantity DESC) AS Rank
FROM Production.ProductInventory AS i
     INNER JOIN Production.Product AS p
         ON i.ProductID = p.ProductID
WHERE i.LocationID BETWEEN 3 AND 4
ORDER BY i.LocationID;

Вот результирующий набор.

ProductID   Name                   LocationID   Quantity Rank
----------- ---------------------- ------------ -------- ----
494         Paint - Silver         3            49       1
495         Paint - Blue           3            49       1
493         Paint - Red            3            41       3
496         Paint - Yellow         3            30       4
492         Paint - Black          3            17       5
495         Paint - Blue           4            35       1
496         Paint - Yellow         4            25       2
493         Paint - Red            4            24       3
492         Paint - Black          4            14       4
494         Paint - Silver         4            12       5

B. Ранжуйте все строки в наборе результатов

В следующем примере приводятся топ-10 сотрудников, ранжированных по их зарплате. Поскольку PARTITION BY предложение не указано, функция RANK применяется ко всем строкам в наборе результатов.

USE AdventureWorks2025;
GO

SELECT TOP (10) BusinessEntityID,
                Rate,
                RANK() OVER (ORDER BY Rate DESC) AS RankBySalary
FROM HumanResources.EmployeePayHistory AS eph1
WHERE RateChangeDate = (
    SELECT MAX(RateChangeDate)
    FROM HumanResources.EmployeePayHistory AS eph2
    WHERE eph1.BusinessEntityID = eph2.BusinessEntityID
)
ORDER BY BusinessEntityID;

Вот результирующий набор.

BusinessEntityID Rate                  RankBySalary
---------------- --------------------- --------------------
1                125.50                1
2                63.4615               4
3                43.2692               11
4                29.8462               28
5                32.6923               22
6                32.6923               22
7                50.4808               6
8                40.8654               14
9                40.8654               14
10               42.4808               13

Примеры: Azure Synapse Analytics

В. Ранжирование строк внутри секции

В приведенном ниже примере торговые представители на каждой территории продаж ранжируются в соответствии с общим объемом продаж. Набор строк секционируется по столбцу SalesTerritoryGroup и сортируется по столбцу SalesAmountQuota.

-- Uses AdventureWorks
SELECT e.LastName,
       st.SalesTerritoryGroup,
       SUM(sq.SalesAmountQuota) AS TotalSales,
       RANK() OVER (PARTITION BY st.SalesTerritoryGroup ORDER BY SUM(sq.SalesAmountQuota) DESC) AS RankResult
FROM dbo.DimEmployee AS e
     INNER JOIN dbo.FactSalesQuota AS sq
         ON e.EmployeeKey = sq.EmployeeKey
     INNER JOIN dbo.DimSalesTerritory AS st
         ON e.SalesTerritoryKey = st.SalesTerritoryKey
WHERE e.SalesPersonFlag = 1
      AND st.SalesTerritoryGroup <> N'NA'
GROUP BY e.LastName, st.SalesTerritoryGroup;

Вот результирующий набор.

LastName           SalesTerritoryGroup  TotalSales   RankResult
------------------ -------------------- ------------ -----------
Pak                Europe               10514000.00  1
Varkey Chudukatil  Europe               5557000.00   2
Valdez             Europe               2287000.00   3
Carson             North America        12198000.00  1
Mitchell           North America        11786000.00  2
Blythe             North America        11162000.00  3
Reiter             North America        8541000.00   4
Ito                North America        7804000.00   5
Saraiva            North America        7098000.00   6
Vargas             North America        4365000.00   7
Campbell           North America        4025000.00   8
Ansman-Wolfe       North America        3551000.00   9
Mensa-Annan        North America        2753000.00   10
Tsoflias           Pacific              1687000.00   1