RANK (Transact-SQL)

适用于:SQL ServerAzure SQL 数据库Azure SQL 托管实例Azure Synapse AnalyticsAnalytics Platform System (PDW)Microsoft Fabric 中的 SQL 分析终结点Microsoft Fabric 中的仓库

返回结果集的分区内每行的排名。 行的排名是相关行之前的排名数加一。

ROW_NUMBER 和 RANK 类似。 ROW_NUMBER 按顺序对所有行进行编号(例如 1、2、3、4、5)。 RANK 为相应关联提供相同的数值(例如 1、2、2、4、5)。

注意

RANK 是运行查询时计算出的临时值。 若要将数值保存在表中,请参阅 IDENTITY 属性SEQUENCE

Transact-SQL 语法约定

语法

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )  

注意

若要查看 SQL Server 2014 (12.x) 及更早版本的 Transact-SQL 语法,请参阅早期版本文档

参数

OVER ( [ partition_by_clause ] order_by_clause)
partition_by_clause 将 FROM 子句生成的结果集划分为要应用函数的分区 。 如果未指定,则此函数将查询结果集的所有行视为单个组。 order_by_clause 在应用函数之前确定数据的顺序 。 需要 order_by_clause 。 不能为 RANK 函数指定 OVER 子句的 <rows 或 range 子句/>。 有关详细信息,请参阅 OVER 子句 (Transact-SQL)

返回类型

bigint

备注

如果两个或多个行与一个排名关联,则每个关联行将得到相同的排名。 例如,如果两位顶尖销售员具有相同的 SalesYTD 值,则他们将并列第一。 由于已有两行排名在前,所以具有下一个最大 SalesYTD 的销售人员将排名第三。 因此,RANK 函数并不总返回连续整数。

用于整个查询的排序顺序决定了行在结果集中的显示顺序。

RANK 具有不确定性。 有关详细信息,请参阅 Deterministic and Nondeterministic Functions

示例

A. 对分区中的行进行排名

以下示例按照数量对指定清单位置的清单中的产品进行了排名。 结果集按 LocationID 分区并在逻辑上按 Quantity 排序。 注意,产品 494 和 495 具有相同的数量。 因为它们是关联的,所以两者均排名第一。

USE AdventureWorks2022;  
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;  
GO  

下面是结果集:

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  
 (10 row(s) affected)  

B. 对结果集中的所有行排名

下面的示例返回按薪金排名的前十名员工。 因为未指定 PARTITION BY 子句,所以,RANK 函数应用于结果集中的所有行。

USE AdventureWorks2022  
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 和 Analytics Platform System (PDW)

C:对分区中的行进行排名

下面的示例根据销售代表的销售总额将每个销售区域中的销售代表进行排名。 行集按 SalesTerritoryGroup 分区,按 SalesAmountQuota 排序。

-- Uses AdventureWorks  
  
SELECT LastName, SUM(SalesAmountQuota) AS TotalSales, SalesTerritoryRegion,  
    RANK() OVER (PARTITION BY SalesTerritoryRegion ORDER BY SUM(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 SalesPersonFlag = 1 AND SalesTerritoryRegion != N'NA'  
GROUP BY LastName, SalesTerritoryRegion;  

下面是结果集。

LastName          TotalSales     SalesTerritoryRegion  RankResult
----------------  -------------  -------------------  --------
Tsoflias          1687000.0000   Australia            1
Saraiva           7098000.0000   Canada               1
Vargas            4365000.0000   Canada               2
Carson            12198000.0000  Central              1
Varkey Chudukatil 5557000.0000   France               1
Valdez            2287000.0000   Germany              1
Blythe            11162000.0000  Northeast            1
Campbell          4025000.0000   Northwest            1
Ansman-Wolfe      3551000.0000   Northwest            2
Mensa-Annan       2753000.0000   Northwest            3
Reiter            8541000.0000   Southeast            1
Mitchell          11786000.0000  Southwest            1
Ito               7804000.0000   Southwest            2
Pak               10514000.0000  United Kingdom       1

另请参阅

DENSE_RANK (Transact-SQL)
ROW_NUMBER (Transact-SQL)
NTILE (Transact-SQL)
排名函数 (Transact-SQL)
内置函数 (Transact-SQL)