CodeGym /コース /SQL SELF /ウィンドウ関数を使った累積合計の計算: SUM(), AVG()

ウィンドウ関数を使った累積合計の計算: SUM(), AVG()

SQL SELF
レベル 29, レッスン 4
使用可能

例えば、自分の会社の収入を追いかけたり、ネットショップの売上を見たり、あるいは単純に自分の1年の支出を分析したいとするよね。毎月の収入や支出を見るだけじゃなくて、月ごとにどれだけ積み上がってるかも知りたいはず。

普通の集約関数(GROUP BY)だと、データをグループ化してグループごとに1行しか返してくれない。でも、毎月のデータを全部見ながら累積合計を出したい場合はどうする?そこでSUM()とウィンドウ関数の出番!

累積合計のためのウィンドウ関数の基本

ウィンドウ関数を使うと、ウィンドウフレームごとに集約処理ができるんだ。つまり、各行ごとに値を足し合わせたりできるけど、他の行を消さずに済む。もうGROUP BYの犠牲になる必要なし!

SUM()とウィンドウ関数の基本構文

累積合計を出すためのベースとなるテンプレートはこれ:

SELECT
    column_name,
    SUM(column_name) OVER (PARTITION BY partition_column ORDER BY order_column) AS cumulative_sum
FROM 
    table_name;

ここで:

  • SUM(column_name) — 値を合計する。
  • OVER() — ウィンドウを指定する。
  • PARTITION BY — データをグループ分け(オプション)。
  • ORDER BY — ウィンドウ内の行の順番を決める。

例:月ごとの累積収入

収入のテーブルがあるとしよう:

月 収入
2023-01 1000
2023-02 1500
2023-03 2000

毎月の収入と累積合計を見たい。SQLクエリを書いてみよう:

SELECT
    月,
    収入,
    SUM(収入) OVER (ORDER BY 月) AS 累積_収入
FROM 
    収入テーブル;

結果:

月 収入 累積_収入
2023-01 1000 1000
2023-02 1500 2500
2023-03 2000 4500

何が起きてるかというと:

  1. OVER()の中のORDER BY 月で、PostgreSQLに「行を時系列順で見てね」と伝えてる。
  2. 各行ごとに、それまでの全ての行(+今の行)を合計してる。

ここ、よく考えてみて。1行目はSUM()で1行目だけ、2行目は2行分、3行目は3行分の合計。だから月の並び順が超大事!

例:地域ごとの累積収入

もし地域ごとの売上テーブルがあったら、こんな感じ:

地域 月 収入
北部 2023-01 1000
北部 2023-02 1500
南部 2023-01 2000
南部 2023-02 2500

今度は、地域ごとに累積収入を計算したい:

SELECT
    地域,
    月,
    収入,
    SUM(収入) OVER (PARTITION BY 地域 ORDER BY 月) AS 累積_収入
FROM 
    売上;

結果はこうなる:

地域 月 収入 累積_収入
北部 2023-01 1000 1000
北部 2023-02 1500 2500
南部 2023-01 2000 2000
南部 2023-02 2500 4500

今度は各地域ごとに分析されてる(PARTITION BY 地域)、でも地域内では時系列順(ORDER BY 月)。

移動平均(AVG())

累積合計も便利だけど、「直近3ヶ月のトレンドを見たい!」みたいな時は移動平均がピッタリ。

例:収入の移動平均

また収入テーブルを使うよ。データはこんな感じ:

月 収入
2023-01 1000
2023-02 1500
2023-03 2000
2023-04 2500

3ヶ月移動平均を出すクエリ:

SELECT
    月,
    収入,
    AVG(収入) OVER (
        ORDER BY 月 
        ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
    ) AS 移動平均
FROM 
    収入;

結果:

月 収入 移動平均
2023-01 1000 1000
2023-02 1500 1250
2023-03 2000 1500
2023-04 2500 2000

解説:

  1. ROWS BETWEEN 2 PRECEDING AND CURRENT ROWは、PostgreSQLに「今の行と2つ前までを見て平均出してね」と伝えてる。
  2. つまり、各月ごとに直近3ヶ月の平均収入が見える。

つまり、各行ごとに3行分(今+2つ前)をウィンドウにして平均を出す。めっちゃ便利!

ORDER BYの動きとその影響

ウィンドウ関数は、行の順番がちゃんとしてないとダメ。順番が変だったり、指定しなかったりすると、結果が予想外になることも。

例:ORDER BYなしのミス

OVER()からORDER BYを外すと、累積合計じゃなくて、全行の合計が毎行に出ちゃう:

SELECT
    月,
    収入,
    SUM(収入) OVER () AS 間違った_累積合計
FROM 
    収入;

結果:

月 収入 間違った累積合計
2023-01 1000 7000
2023-02 1500 7000
2023-03 2000 7000
2023-04 2500 7000

行の順番がなくなって、累積合計じゃなくて、全行の合計が毎行に出てきちゃう。

リアルな使い方ケース

収入分析:

  • 累積合計で、会社の売上や収入の伸びを追える。
  • 移動平均で、ノイズのない「本当の」トレンドが見える。

ファイナンシャルモデリング:

銀行や金融系の会社は、ウィンドウ関数で支払い分析や債務の増加、他の指標を見てる。

時系列データの分析:

オンラインユーザー数、ページビュー、売上などの時系列データは、SUM()やAVG()で分析するのがピッタリ。

2
タスク
SQL SELF, レベル 29, レッスン 4
ロック未解除
直近3か月間の移動平均
直近3か月間の移動平均
1
アンケート/クイズ
ウィンドウ関数、レベル 29、レッスン 4
使用不可
ウィンドウ関数
ウィンドウ関数
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION