ランク(Transact-SQL)

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsMicrosoft Fabric の SQL 分析エンドポイントMicrosoft Fabric のウェアハウスMicrosoft Fabric の SQL データベース

結果セットのパーティション内の各行の順位を返します。 行の順位は、その行より上にある順位の数に 1 を加えたものです。

ROW_NUMBERRANK は似ています。 ROW_NUMBER は、すべての行に順番に番号を付けます (たとえば 1、2、3、4、5)。 RANK は、同順位に対して同じ番号を付けます (たとえば 1、2、2、4、5)。

Note

RANK は、クエリの実行時に計算される一時的な値です。 テーブルに数値を永続化するには、 IDENTITY (プロパティ) および CREATE SEQUENCEを参照してください。

Transact-SQL 構文表記規則

構文

RANK ( ) OVER ( [ partition_by_clause ] order_by_clause )

引数

オーバー([ partition_by_clause ] order_by_clause )

partition_by_clauseは、FROM節によって生成された結果集合を、関数が適用されるパーティションに分割します。 指定しない場合、関数ではクエリ結果セットのすべての行を 1 つのグループとして扱います。

order_by_clause は、関数を適用する前にデータの順序を決定します。 order_by_clause が必要です。 <rows or range clause>節のOVERRANK関数に対して指定できません。 詳細については、 SELECT - OVER 句を参照してください。

戻り値の型

bigint

解説

複数の行が 1 つの順位を分け合う場合は、それぞれの行に同じ順位が付けられます。 例えば、トップ2の営業担当者が同じ SalesYTD 価値を持つ場合、両方とも1ランクにされます。 次に高い SalesYTD を持つ営業担当者は3位にランクされます。なぜなら、2つの列が上位にランクされているからです。 したがって、 RANK 関数は必ずしも連続した整数を返すわけではありません。

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

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

ウィンドウ関数のパフォーマンス調整ガイダンスについては、 OVER() パフォーマンスの考慮事項を参照してください。

この記事のコードサンプルは、Azure Data SQL Samples Repository GitHub repositoryからダウンロードできるAdventureWorks2025またはAdventureWorksDW2025サンプルデータベースを使用しています。

A. パーティション内のランク行

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

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

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

次の例では、売上合計に応じて販売区域ごとに販売担当者をランク付けします。 行セットは 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