ウィンドウ関数は、現在の行に関連する行セット全体で計算を実行するために使用される SQL の強力な機能です。集計関数とは異なり、ウィンドウ関数は行を 1 つの出力にグループ化しません。データセットのコンテキストを維持しながら、各行の結果を返します。
この記事では、よく使用される SQL ウィンドウ関数 ( ROW_NUMBER()
、 RANK()
、 DENSE_RANK()
、 NTILE()
、 LEAD()
、 LAG()
) について例を挙げて説明します。
ウィンドウ関数を説明するために、次の Sales テーブルを使用します。
セールスID | 顧客ID | 製品 | 地域 | 額 | 販売日 |
---|---|---|---|---|---|
1 | 101 | ラップトップ | 北 | 1200 | 2023-01-05 |
2 | 102 | 錠剤 | 北 | 800 | 2023-02-15 |
3 | 103 | 電話 | 北 | 800 | 2023-03-10 |
4 | 104 | 錠剤 | 北 | 500 | 2023-04-01 |
5 | 105 | ラップトップ | 南 | 1300 | 2023-05-05 |
6 | 106 | 錠剤 | 南 | 700 | 2023-06-20 |
7 | 107 | 電話 | 西 | 900 | 2023-07-15 |
8 | 108 | ラップトップ | 東 | 1300 | 2023-08-10 |
ROW_NUMBER() 関数は、指定された列の順序に従って、パーティション内の各行に一意の番号を割り当てます。
タスク: 売上金額(最高から最低)に基づいて、地域内の各売上に一意の行番号を割り当てます。
SELECT SalesID, Region, Amount, ROW_NUMBER() OVER (PARTITION BY Region ORDER BY Amount DESC) AS RowNum FROM Sales;
結果:
セールスID | 地域 | 額 | 行番号 |
---|---|---|---|
1 | 北 | 1200 | 1 |
2 | 北 | 800 | 2 |
3 | 北 | 800 | 3 |
4 | 北 | 500 | 4 |
5 | 南 | 1300 | 1 |
6 | 南 | 700 | 2 |
7 | 西 | 900 | 1 |
8 | 東 | 1300 | 1 |
RANK() 関数は、パーティション内の各行にランクを割り当てます。同じ値を持つ行は同じランクを受け取り、次のランクはスキップされます。
タスク: 各地域内の売上高を金額順にランク付けします (最高から最低の順)。
SELECT SalesID, Region, Amount, RANK() OVER (PARTITION BY Region ORDER BY Amount DESC) AS Rank FROM Sales;
結果:
セールスID | 地域 | 額 | ランク |
---|---|---|---|
1 | 北 | 1200 | 1 |
2 | 北 | 800 | 2 |
3 | 北 | 800 | 2 |
4 | 北 | 500 | 4 |
5 | 南 | 1300 | 1 |
6 | 南 | 700 | 2 |
7 | 西 | 900 | 1 |
8 | 東 | 1300 | 1 |
主な特徴:
DENSE_RANK() 関数は RANK() のようにランクを割り当てますが、同点の後のランクをスキップしません。
タスク: 各地域内の売上高に金額別 (最高から最低) に稠密なランクを割り当てます。
SELECT SalesID, Region, Amount, DENSE_RANK() OVER (PARTITION BY Region ORDER BY Amount DESC) AS DenseRank FROM Sales;
結果:
セールスID | 地域 | 額 | デンスランク |
---|---|---|---|
1 | 北 | 1200 | 1 |
2 | 北 | 800 | 2 |
3 | 北 | 800 | 2 |
4 | 北 | 500 | 3 |
5 | 南 | 1300 | 1 |
6 | 南 | 700 | 2 |
7 | 西 | 900 | 1 |
8 | 東 | 1300 | 1 |
主な特徴:
NTILE() は、行を指定された数のほぼ等しいグループに分割します。
タスク: 金額に基づいてすべての売上を降順で 4 つのグループに分けます。
SELECT SalesID, Amount, NTILE(4) OVER (ORDER BY Amount DESC) AS Quartile FROM Sales;
結果:
セールスID | 額 | 四分位 |
---|---|---|
5 | 1300 | 1 |
8 | 1300 | 1 |
1 | 1200 | 2 |
7 | 900 | 2 |
2 | 800 | 3 |
3 | 800 | 3 |
4 | 500 | 4 |
6 | 700 | 4 |
LEAD() は、同じパーティション内の次の行から値を取得します。
タスク: SaleDate 順に並べられた各販売額を次の販売額と比較します。
SELECT SalesID, Amount, LEAD(Amount) OVER (ORDER BY SaleDate) AS NextAmount FROM Sales;
結果:
セールスID | 額 | 次の金額 |
---|---|---|
1 | 1200 | 800 |
2 | 800 | 800 |
3 | 800 | 500 |
4 | 500 | 1300 |
5 | 1300 | 700 |
6 | 700 | 900 |
7 | 900 | 1300 |
8 | 1300 | NULL |
LAG()
同じパーティション内の前の行から値を取得します。
タスク: SaleDate 順に並べられた各販売額を前回の販売額と比較します。
SELECT SalesID, Amount, LAG(Amount) OVER (ORDER BY SaleDate) AS PrevAmount FROM Sales;
結果:
セールスID | 額 | 前金額 |
---|---|---|
1 | 1200 | NULL |
2 | 800 | 1200 |
3 | 800 | 800 |
4 | 500 | 800 |
5 | 1300 | 500 |
6 | 700 | 1300 |
7 | 900 | 700 |
8 | 1300 | 900 |
ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()、LEAD()、LAG() などの SQL ウィンドウ関数は、パーティション内のデータを分析するための強力な方法を提供します。
重要なポイント:
ROW_NUMBER()
各行に一意の識別子を割り当てます。RANK()
とDENSE_RANK()
、同点の処理方法 (スキップするかスキップしないか) が異なります。NTILE()
、行を統計グループに分割するのに役立ちます。LEAD()
とLAG()
隣接する行との比較が可能になります。
これらの機能を習得することで、複雑な分析やランキングタスクを効果的に処理できるようになります。
データ関連の洞察を私と一緒に探求するために時間を割いていただき、ありがとうございます。あなたの関与に感謝します。この情報が役に立ったと思われる場合は、ぜひ私をフォローするか、 LinkedInで私とつながってください。探索を楽しんでください!👋