SQLウィンドウ関数入門|RANK・LEAD・LAGで始める実践データ分析

SQL & DB

「ウィンドウ関数って何?」

SQLに慣れてきたある日、そんな単語が登場しました。

…でも正直、最初に名前だけ聞いたときは、私こう思いました。

「え、Excelのウインドウ枠固定の仲間…?」

「画面分割とか表示系の話?」 まったく違いました…笑

実はこのウィンドウ関数、“行ごとにデータを比べたり、順番をつけたりできる”という、とっても便利な機能なんです。

「前の人の値と比べて◯◯」とか、「この行の順位は◯位」みたいなことが、SQLだけでサクッとできるなんてすごくないですか?

本記事では、ウィンドウ関数のなかでもよく使われる「RANK・LEAD・LAG」を、初心者の方にもわかりやすく&実践で使える形でご紹介します。

SQLでもう一歩先の分析をしてみたい方、ぜひ肩の力を抜いて読んでみてくださいね!

  1. 「ウィンドウ関数」ってなんだろう?まずはざっくり理解
    1. ウィンドウ関数=1行ずつの“窓”から全体をのぞくイメージ
    2. ウィンドウ関数と集計関数の違いは?
    3. 「ウィンドウ関数って難しい?」→いいえ、こう考えればOK!
    4. まとめ:ウィンドウ関数=「行ごとに、他の行と比較しながらデータを扱う」技術
  2. RANK()関数でランキングを作ってみよう
    1. RANK()の基本構文
    2. 実践①:売上ランキングを出してみよう!
    3. RANK()とDENSE_RANK()の違いは?
    4. まとめ:SQLで順位をつけるのは意外と簡単!
  3. LEAD()/LAG()で前後のデータをのぞいてみよう
    1. LEAD() と LAG() の基本構文
    2. 実践①:昨日と今日の売上を比較してみよう!
    3. 実践②:次の日の売上は? LEAD() を試してみよう!
    4. LEAD() / LAG() を組み合わせて「変化」を見てみよう!
    5. まとめ:前後のデータを見て、流れをつかむ
  4. ウィンドウ関数の定番パターンを実務で活用しよう
    1. 累積売上の計算(SUM() OVER)
    2. グループごとのランキング(PARTITION BY を活用)
    3. ウィンドウ関数の活用で、データ分析の幅が広がる!
  5. ウィンドウ関数と集計関数はどう違う?使い分けのコツ
    1. 違いを一言で説明すると…?
    2. 一方、ウィンドウ関数は「各行の情報を残しながら計算」
    3. 簡単な使い分けルール
    4. 実務での具体的な使い分け例
    5. まとめ:「データをどう見たいか?」で選ぶ!
  6. まとめ&次に学ぶべきウィンドウ関数の世界へ
    1. 次に学ぶべきウィンドウ関数の一覧
    2. ウィンドウ関数を活用するコツ
    3. まとめ:ウィンドウ関数をマスターすれば、SQL分析がもっと楽しくなる!

「ウィンドウ関数」ってなんだろう?まずはざっくり理解

SQLを学んでいると、ある日突然「ウィンドウ関数」という謎の言葉に出会います。

名前の響きだけで「え、何か画面を分割する系の関数…?」と思った方、それは私と同じ初見のリアクションですね。

でも実は、ウィンドウ関数の役割はすごくシンプル。

「データを行ごとに扱いながらも、全体の情報も使って計算する」ことができるんです!

ウィンドウ関数=1行ずつの“窓”から全体をのぞくイメージ

ウィンドウ関数を使うと、SQLが「今この行に注目してるけど、他の行の情報も参照したいな~」と考えられるようになります。

例えば、こんな質問

  • 「この商品の売上順位は?」 → RANK() を使えばOK!
  • 「この行の次のデータは?」 → LEAD() が教えてくれる!
  • 「前回のデータと比較したい!」 → LAG() でできる!

SQLなのに“他の行を見ながら処理できる”なんて、ちょっと賢すぎませんか?

ウィンドウ関数と集計関数の違いは?

ウィンドウ関数を理解するには、「普通の集計関数(SUM, AVG)」と何が違うの?」を押さえておくとスムーズです。

内容集計関数 (SUM(), AVG())ウィンドウ関数 (RANK(), LEAD(), LAG())
計算単位全体でまとめて1つの値を出す各行ごとに計算するが、他の行の情報も参照する
出力結果 1行に集約(例:売上合計だけ)全行に結果を表示(例:各商品の順位を出す)
具体例「売上合計は◯円」「この商品の売上順位は◯位」

集計関数は全体をまとめるイメージ、ウィンドウ関数は各行を見ながら処理するイメージ。

この違いを押さえておくだけで、ウィンドウ関数がグッと理解しやすくなります!

「ウィンドウ関数って難しい?」→いいえ、こう考えればOK!

ウィンドウ関数は、言ってしまえば「今この行にフォーカスしつつ、他の情報も参考にする技術」です。

人間でいうなら、「自分のことを考えつつ、周りの状況も気にする」みたいなものですね!

例えば、RANK関数で売上順位をつける場面を考えてみると…

SQL
SELECT product_name, sales,
RANK() OVER(ORDER BY sales DESC) AS 売上順位
FROM products;

このクエリを実行すると、各商品の売上順位がズラッと表示されます。

何かを並べたり、ランキングを作るときに超便利ですね!

まとめ:ウィンドウ関数=「行ごとに、他の行と比較しながらデータを扱う」技術

  • SQLのウィンドウ関数は、「行を見ながら他の情報も使う」特別な関数
  • 集計関数との違いは、「全体で集約するか、各行に適用するか」
  • RANK(), LEAD(), LAG() を使えば、順位や前後関係を簡単に取得できる!

次章では「RANK関数を使ってランキングを作る」実践編へ! 実際に手を動かしてみると、ウィンドウ関数の面白さがもっと感じられますよ。

RANK()関数でランキングを作ってみよう

SQLでデータを扱っていると、たまにこんな疑問がわきませんか?

「この商品の売上順位は?」

「テストの得点、誰がトップ?」

「営業成績をランキングで見たい!」

この「順位をつける」問題をサクッと解決できるのが RANK()関数 です!

RANK()の基本構文

SQL
SELECT 列1, 列2, 
       RANK() OVER(ORDER BY 順序を決める列 DESC) AS 順位
FROM テーブル名;

ポイント

  • ORDER BY で「何を基準に順位をつけるか」決める
  • DESC にすると「大きい順」、ASC にすると「小さい順」

実践①:売上ランキングを出してみよう!

例えば、以下のような products テーブル があるとします

商品名売上金額
スマホ100万
ノートPC150万
タブレット80万

「売上順にランキングをつけたい!」ときは、こう書きます

SQL
SELECT product_name, sales,
       RANK() OVER(ORDER BY sales DESC) AS 売上順位
FROM products;

結果

商品名売上金額売上順位
ノートPC150万1位
スマホ100万2位
タブレット80万3位

これだけで、 「売れた順」 に並べられました! もうExcelの手動ソートとはサヨナラですね。

RANK()とDENSE_RANK()の違いは?

例えば、売上が同じ商品があったらどうなるでしょう?

商品名売上金額
スマホ 100万
ノートPC150万
タブレット100万

このとき、 RANK() を使うとこうなります

SQL
SELECT product_name, sales,
       RANK() OVER(ORDER BY sales DESC) AS 売上順位
FROM products;
商品名売上金額 RANK順位
ノートPC 150万1位
スマホ 100万2位
タブレット100万2位

→ 同じ売上の商品は 「同順位」 になります! でも、次の順位は「4位」になり “番号が飛ぶ” のが特徴。

一方で、 DENSE_RANK() を使うと…

SQL
SELECT product_name, sales,
       DENSE_RANK() OVER(ORDER BY sales DESC) AS 売上順位
FROM products;
商品名売上金額 RANK順位
ノートPC 150万1位
スマホ 100万2位
タブレット100万2位

→ RANK()と同じく 「同順位OK」 だけど、次の順位が「3位」になる! 番号の“飛び”がないのが DENSE_RANK()の特徴 です。

どっちを使う?

  • 通常のランキングなら RANK() でOK!
  • 「順位が連続してほしい」場面では DENSE_RANK() が便利!

まとめ:SQLで順位をつけるのは意外と簡単!

  • RANK()関数 を使えば ランキングが一発で作れる
  • DENSE_RANK() は「同順位の次の番号を飛ばさない」特徴あり
  • 売上・得点・営業成績など、順位データの分析にめちゃくちゃ役立つ!

次章では、「前後のデータを参照する」 LEAD() / LAG()関数 に入ります!

前回値や次の値を比較するテクニックも、データ分析には欠かせません。

LEAD()/LAG()で前後のデータをのぞいてみよう

「前回の売上と比べて、伸びてる?それとも下がってる?」

「昨日のPVと今日のPV、どっちが多い?」

「この商品の次に売れたのはどれ?」

こんな“時系列の比較”や“データの流れ”を知りたい場面って、よくありますよね。

その悩みを SQLでスマートに解決 できるのが LEAD() と LAG() です!

LEAD() と LAG() の基本構文

SQL
LEAD(対象列, n) OVER(ORDER BY 並べる列)  -- 「n個後のデータ」を取得  
LAG(対象列, n) OVER(ORDER BY 並べる列)   -- 「n個前のデータ」を取得

ポイント

  • LEAD() → 次の行 のデータを参照する
  • LAG() → 前の行 のデータを参照する
  • n → 何行分のデータを見るか(省略すると「1個先・前」)

これを使えば、「前回との差」や「次の値との関係」 を楽にチェックできます!

実践①:昨日と今日の売上を比較してみよう!

sales テーブル を見てみましょう

日付商品名売上金額
2024-06-15スマホ100万
2024-06-16スマホ120万
2024-06-17スマホ90万

「昨日の売上と比べてどう?」 を確認したいときは、こう書きます

SQL
SELECT 日付, 商品名, 売上金額,
       LAG(売上金額, 1) OVER(ORDER BY 日付) AS 昨日の売上
FROM sales;

結果

日付 商品名売上金額昨日の売上
2024-06-15スマホ100万NULL
2024-06-16スマホ 120万 100万
2024-06-17スマホ 90万120万

これで「昨日との差」を一目でチェックできます!

つまり、 LAG() を使えば、「前のデータ」 を簡単に参照できるんです!

実践②:次の日の売上は? LEAD() を試してみよう!

逆に、「この日の次の売上がどうなるか?」を知りたいときは LEAD() の出番です

SQL
SELECT 日付, 商品名, 売上金額,
       LEAD(売上金額, 1) OVER(ORDER BY 日付) AS 次の日の売上
FROM sales;

結果

日付商品名売上金額次の日の売上
2024-06-15スマホ100万120万
2024-06-16スマホ 120万90万
2024-06-17スマホ90万NULL

これなら、未来のトレンドもつかみやすい!

LEAD() を使えば、「次に来るデータ」 を手軽に取り出せます。

LEAD() / LAG() を組み合わせて「変化」を見てみよう!

売上の「変化」を知りたいなら、LAG() を使って “昨日との差額” を計算してみましょう

SQL
SELECT 日付, 商品名, 売上金額,
       LAG(売上金額) OVER(ORDER BY 日付) AS 昨日の売上,
       売上金額 - LAG(売上金額) OVER(ORDER BY 日付) AS 売上変化
FROM sales;

結果

日付商品名売上金額昨日の売上売上変化
2024-06-15スマホ100万 NULLNULL
2024-06-16 スマホ 120万 100万+20万
2024-06-17スマホ90万120万-30万

「今日は昨日より売上アップ?ダウン?」 が一目瞭然。

こうやってデータの変動をチェックすれば、トレンドの把握 や 成績管理 に活用できます!

まとめ:前後のデータを見て、流れをつかむ

  • LAG() → 「前の行のデータ」 を取得(昨日の売上など)
  • LEAD() → 「次の行のデータ」 を取得(次の日の予測など)
  • 変化を計算すると 「どれくらい増えた?減った?」 が簡単にわかる!

次章では、 ウィンドウ関数の定番パターンを実務で活用する 方法へ。

累積売上・順位の安定化・前後比較など、さらに実践的なテクニックを掘り下げていきます!

ウィンドウ関数の定番パターンを実務で活用しよう

ここまで RANK(), LEAD(), LAG() の基本を学んできましたね!

しかし、ウィンドウ関数はこれらだけではありません。

「ランキングを作る」「前後比較をする」だけでなく、 「累積集計」や「グループごとの傾向分析」 までこなせる、とても強力な技術なんです。

この章では、 実務でよく使うウィンドウ関数のパターン を掘り下げていきましょう!

累積売上の計算(SUM() OVER)

例えば、ある商品の 累積売上(累積合計) を出したいとします。

日付商品名売上金額
2024-06-01スマホ10万
2024-06-02スマホ 15万
2024-06-03スマホ20万

累積売上を出したいとき、通常のSUM()だと「全体の合計値」しか取れませんが、 ウィンドウ関数のSUM()を使えば、日ごとの累積売上を出せます!

SQL
SELECT 日付, 商品名, 売上金額,
       SUM(売上金額) OVER(ORDER BY 日付) AS 累積売上
FROM sales;

結果

日付商品名売上金額累積売上
2024-06-01スマホ10万10万
2024-06-02スマホ15万25万
2024-06-03スマホ20万45万

「この時点でどれくらい売れているか?」が簡単にわかる! 営業成績や、売上達成率のモニタリングにも便利ですね。

グループごとのランキング(PARTITION BY を活用)

例えば「各店舗ごとの売上ランキング」を出したい場面を考えてみましょう。

店舗名商品名売上金額
東京店スマホ120万
東京店タブレット80万
大阪店スマホ 100万
大阪店タブレット95万

各店舗ごとに「売上ランキング」をつけるなら、 PARTITION BY 店舗名 を使えばOK!

SQL
SELECT 店舗名, 商品名, 売上金額,
       RANK() OVER(PARTITION BY 店舗名 ORDER BY 売上金額 DESC) AS 売上順位
FROM sales;

結果

店舗名商品名売上金額売上順位
東京店スマホ120万1位
東京店タブレット80万2位
大阪店 タブレット95万 1位
大阪店スマホ 100万2位

「各店舗ごとのランキング」を作れる! 地域ごとの売上戦略を立てる際に、こうしたデータが重宝されます。

ウィンドウ関数の活用で、データ分析の幅が広がる!

  • 累積データを計算(SUM() OVER) → 日々の積み重ねをチェック
  • グループ別ランキングを作成(PARTITION BY) → 部署ごと、店舗ごとなど集計できる
  • 前後比較(LAG(), LEAD()) → 昨日との差、未来の予測に活用

こういったテクニックを組み合わせることで、 「データをただ並べる」から「データに意味を持たせる」へ進化 できます!

次章では、 ウィンドウ関数と集計関数の違い&使い分けのコツ を解説していきます。

もう「SQLで高度な分析ができる自分」に近づいてきましたね!

ウィンドウ関数と集計関数はどう違う?使い分けのコツ

SQLを学んでいると、最初に出てくるのは SUM(), AVG(), COUNT() などの集計関数 ですよね。

データをまとめて「合計」「平均」などを算出するシンプルな関数ですが……

その後に ウィンドウ関数(RANK(), LAG(), LEAD() など) が出てきて、

「どっちを使えばいいの?」「どう違うの?」と混乱することがあるかもしれません。

実は、 集計関数とウィンドウ関数は目的が違う んです。

この章では、 その違いと使い分けのコツ を解説していきます!

違いを一言で説明すると…?

集計関数 ➡ 「データをまとめて、1つの結果を出す」

ウィンドウ関数 ➡ 「各行のデータを見ながら、他の情報も使う」

例えば

商品名売上金額
スマホ100万
ノートPC150万
タブレット80万

このデータで 売上の「合計」 を出したいなら、集計関数を使います。

SQL
SELECT SUM(売上金額) AS 総売上
FROM products;

結果

総売上
330万

→ データ全体をまとめて、1つの結果を出す のが集計関数!

一方、ウィンドウ関数は「各行の情報を残しながら計算」

同じデータで 「各商品の売上順位」 を出したいなら、ウィンドウ関数が登場。

SQL
SELECT 商品名, 売上金額,
RANK() OVER(ORDER BY 売上金額 DESC) AS 売上順位
FROM products;

結果

商品名売上金額売上順位
ノートPC150万1位
スマホ100万2位
タブレット80万3位

→ 各行のデータをそのまま保持しつつ、「順位」をつけるのがウィンドウ関数!

簡単な使い分けルール

目的使う関数
全体の「合計・平均」を出す集計関数 (SUM(), AVG() など)
データをグループごとにまとめる集計関数 (GROUP BY とセット)
各行に「順位」をつけるウィンドウ関数 (RANK(), DENSE_RANK() など)
各行ごとに「前後のデータ」を参照ウィンドウ関数 (LEAD(), LAG() など)

「一つの数値を出すなら集計関数」「各行の情報を残すならウィンドウ関数」 のイメージでOK!

実務での具体的な使い分け例

例えば 「売上レポート」を作る場合、こんな使い分けができます。

  • 全体の売上合計 ➡ 集計関数 (SUM())
  • カテゴリーごとの平均売上 ➡ 集計関数 (GROUP BY + AVG())
  • 各商品の売上順位 ➡ ウィンドウ関数 (RANK())
  • 前日との差額を出す ➡ ウィンドウ関数 (LAG())

まとめ:「データをどう見たいか?」で選ぶ!

  • 「全体の数値を出したい」なら 集計関数!
  • 「各行のデータを保持しながら計算したい」なら ウィンドウ関数!
  • 「順位」「前後の値」「累積計算」などが必要なら ウィンドウ関数が最適!

この使い分けを押さえておけば、SQLの分析力が グッと上級者レベル に進化します。

次章では 「さらに高度なウィンドウ関数」 について解説! SQLでできることが、もっと広がっていきますよ。

まとめ&次に学ぶべきウィンドウ関数の世界へ

ここまでで、ウィンドウ関数の基本 RANK(), LEAD(), LAG() について学びましたね。

この記事を読んだことで、あなたは 「SQLで順位をつける」「前後データを参照する」「累積計算をする」 という分析技術を手に入れました。

しかし、ウィンドウ関数の世界は まだまだ広い のです!

この章では、次にステップアップするためのおすすめ機能と、実務で活用するコツをご紹介します。

次に学ぶべきウィンドウ関数の一覧

ウィンドウ関数には、これまで学んだ RANK(), LEAD(), LAG() 以外にも強力な機能がそろっています。

関数名できること使いどころ
ROW_NUMBER()各行に 「連番」 を振るID付与、ページ分割など
NTILE(n)データを 「n等分」 してグループ化四分位数分析など
FIRST_VALUE()グループごとの 「最初の値」 を取得各カテゴリの代表値
LAST_VALUE() グループごとの 「最後の値」 を取得期間ごとの最新データ

例えば、 ROW_NUMBER() を使えば「1, 2, 3…」と連番を振れるので、 ページングやレポート作成に便利 です!

ウィンドウ関数を活用するコツ

  • 「このデータ、どう分析したい?」から考える
     → 順位?累積?前後比較?それに合う関数を選ぶ
  • ORDER BY をしっかり指定する
     → ウィンドウ関数は 並び順が超重要! 「何を基準に計算するか」を明確に
  • PARTITION BY でグループ分けを適切に設定
     → 「全体なのか、カテゴリごとなのか」を意識すると、より正確なデータが取れる!

まとめ:ウィンドウ関数をマスターすれば、SQL分析がもっと楽しくなる!

  • ウィンドウ関数は「各行を見ながら計算する」強力なツール
  • RANK(), LEAD(), LAG() を使えば、順位付け&前後比較が簡単!
  • もっと深い分析をしたいなら、ROW_NUMBER(), NTILE() などにも挑戦!

今後は「時系列分析」「KPI評価」「高度なランキング」 など、 ウィンドウ関数を活かした実務的なデータ分析にも挑戦できます。

SQLの分析力をもっと伸ばして、データと楽しく会話できるスキルを磨いていきましょう!

decopon
decopon

ウィンドウ関数という、ちょっととっつきにくい名前の技術も、 実際に試してみると 「思ったより使いやすいかも!」 と思えたのではないでしょうか?

SQLは、ただのデータ抽出ツールではなく、「数字に意味を持たせる魔法」 のようなものです。 今回学んだ RANK(), LEAD(), LAG() を活用すれば、 データがただの数字ではなく 「ストーリーを語る存在」 に変わります。

次のステップへ進む準備は、もうできています! この知識を使って、ぜひ 自分のデータで実験しながらスキルを伸ばしてみてくださいね。

コメント

タイトルとURLをコピーしました