最初は、SQLにはデータ分析に必要なものが全部揃ってるように見えるよね:GROUP BY、集約関数、サブクエリ... でもそれはほんの始まり。ウィンドウ関数の世界へようこそ ― これはデータを1行ずつ扱いながら、全体のコンテキストも保てる強力なツールなんだ。
ウィンドウ関数を使うと、合計や平均、ランキングなどの計算を「ウィンドウ」内の行でできる。しかもデータをまとめずにね。つまり、普通の集約関数(SUM()、AVG()、COUNT())と違って、結果も詳細も各行で見れるってこと!
例えば、注文ごとの累積収入を計算したいとする。GROUP BYだと個々の注文が消えちゃって、合計だけ残る。でもウィンドウ関数なら、結果を各行に追加できて、何も失わないんだ。
ウィンドウ関数が特に便利なのは、データを壊さないこと。各行はそのままで、計算結果が新しいカラムとして追加されるだけ。だから複雑な分析もサブクエリやごちゃごちゃした構文なしでできる ― 1つのクエリで全部完結!ランキングや移動平均、行同士の値比較みたいなタスクにピッタリ。コードも読みやすいし、結果もバッチリ。
こんな時に特に便利:
- 社員・販売員・商品のランキング ― 誰が何位か知りたいとき。
- 時系列データ ― 日ごとや週ごとの変化を見たいとき。
- 売上やファイナンス ― 各ステップでどれだけ溜まったか、どの注文が平均より上か、トップ25%は誰か、など。
ウィンドウ関数はどこで使う?
コンテキストが大事な場面ならどこでも使えるよ:
- 売上レポート;
- 顧客行動の分析;
- 累積メトリクス付きのグラフ作成;
- データのセグメント化(例えば四分位ごと);
- 偏差やトレンドの計算。
SQLで毎日分析してる人には本当にありがたい存在! 実際の現場でウィンドウ関数が救世主になる例をいくつか見てみよう。
例1: データのランキング
例えば、学生のテストの点数リストがあるとする。それぞれの学生にクラス内での順位をつけたい。ウィンドウ関数なら超カンタン。RANK()やROW_NUMBER()を使えばすぐできるよ。
例2: 時系列データの分析
会社の収入が月ごとにどう変化したか調べたい?収入の累積合計が必要だね。ウィンドウ関数のSUM()を特定のウィンドウで使えば、簡単に出せるよ。
例3: 四分位やグループ分け
データを均等なグループ(例えば収入ごと)に分けて顧客をセグメント化したい?そんな時はNTILE()が助けてくれる。誰がトップ25%で、誰が下位なのかもすぐ分かる。
どんな感じ?
ウィンドウ関数は、結果をそのままデータセットに追加するだけ:
SELECT
student_id,
grade,
RANK() OVER (ORDER BY grade DESC) AS rank
FROM
students;
これで、各学生にその点数でのユニークな順位がついたテーブルができる。
簡単な例え
友達グループでランニングしてると想像してみて。みんな自分のペースで走ってるけど、今自分が何位か知りたい。GROUP BYみたいに全員止めてリーダーボードを作るんじゃなくて、周りを見て今の順位を把握する感じ。
これがウィンドウ関数!レースを止めたりグループ分けしたりせず、情報を追加するだけで動きも詳細もそのまま。みんな走り続けてるけど、追加の分析 ― 例えば前に何人いるか、平均と比べて自分のペースはどうか、など ― もできる。
従来のやり方との違い・メリット
よくある課題:営業担当者の収入ランキングを出したい。やり方は2つ:
ウィンドウ関数なし。まずサブクエリ(場合によっては複数)でデータを並べ替えて、番号を振る。長いし、読みにくい。
ウィンドウ関数あり。たった1つのクエリで、きれいで分かりやすい構文。例えば:
SELECT
seller_id,
revenue,
RANK() OVER (PARTITION BY region ORDER BY revenue DESC) AS rank_in_region
FROM
sales;
このクエリは、販売員を地域ごとに分けて、収入の多い順に番号を振ってくれる。
リアルな例
今度は自分がアナリストで、売上データを分析してると想像してみて。知りたいのは:
- 各月の合計収入、
- 前月と比べて収入がどう変わったか、
- 地域ごとの総収入ランキング。
これ全部、ウィンドウ関数を使えば1つのクエリでもできるよ。でもこれは次の講義で詳しくやるね。
これでウィンドウ関数の基礎はバッチリ!次は構文を見て、ROW_NUMBER()、RANK()、DENSE_RANK()、NTILE()のパワーを体感しよう。次の講義へGO!
GO TO FULL VERSION