RANK (Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics 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)。

Note

RANK は、クエリの実行時に計算される一時的な値です。 番号をテーブルに保持するには、「IDENTITY プロパティ」と「SEQUENCE」をご覧ください。

Transact-SQL 構文表記規則

構文

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )  

Note

SQL Server 2014 (12.x) 以前のバージョンの Transact-SQL 構文を確認するには、以前のバージョンのドキュメントを参照してください。

引数

OVER ( [ partition_by_clause ] order_by_clause)
partition_by_clause は、FROM 句で生成された結果セットをパーティションに分割します。このパーティションに関数が適用されます。 指定しない場合、関数ではクエリ結果セットのすべての行を 1 つのグループとして扱います。 order_by_clause は、関数を適用する前にデータの順序を決定します。 order_by_clause が必要です。 OVER 句の は、RANK 関数では指定できません。 詳細については、OVER 句 (Transact-SQL) に関する記事を参照してください。

戻り値の型

bigint

解説

複数の行が 1 つの順位を分け合う場合は、それぞれの行に同じ順位が付けられます。 たとえば、上位 2 人の販売員の SalesYTD 値が同じである場合は、両方に順位 1 が付けられます。 SalesYTD が次に高い販売員には、順位 3 が付けられます。順位のより高い行が 2 つあるためです。 そのため、RANK 関数は連続した整数を返すとは限りません。

クエリ全体に使用される並べ替え順によって、結果セットにおける行の順序が決まります。

RANK は非決定的です。 詳細については、「 決定的関数と非決定的関数」を参照してください。

A. パーティション内の行に順位を付ける

次の例では、指定された在庫場所の在庫内の製品を数量に応じて順位付けしています。 結果セットは LocationID によってパーティションに分割され、Quantity によって論理的に順序付けされます。 494 と 495 の製品が同じ数量であることを確認します。 これらは数量が同じなので、両方とも順位が 1 位になっています。

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. 結果セット内のすべての行に順位を付ける

次の例では、給与に順位を付け、トップ 10 の従業員を返します。 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)