0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

「集計したい」時、GROUP BYを使うべきかウィンドウ関数を使うべきか迷う方は多いはずです。本記事では両者の本質的な違いと、実務での判断基準を整理します。

ウィンドウ関数についての記事

この後の流れ

  1. 最大の違い:行数が変わるか変わらないか
  2. 同じ元データでの出力比較
  3. 使い分けの判断基準
  4. 両方を組み合わせるケース
  5. まとめ

1. 最大の違い:行数が変わるか変わらないか

観点 GROUP BY ウィンドウ関数(OVER)
出力行数 グループ数に集約される(減る) 元の行数を維持する
明細データ 失われる(集計値のみ残る) 明細を保持しつつ集計値を付与できる
SELECT句の制約 集計関数か、GROUP BYの列のみ 通常の列も集計値も同時に書ける
主な用途 サマリーレポート、集計表 ランキング、累計、前後比較、明細+集計の同時出力

2. 同じ元データでの出力比較

元データ:社員ごとの給与(部署A, B)

GROUP BYの場合(部署ごとに集約)

SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department;
department avg_salary
A 450
B 500

→ 社員個人の情報は失われ、2行に集約される。

ウィンドウ関数の場合(明細を維持)

SELECT
    employee_name,
    department,
    salary,
    AVG(salary) OVER (PARTITION BY department) AS dept_avg_salary
FROM employees;
employee_name department salary dept_avg_salary
田中 A 400 450
佐藤 A 500 450
鈴木 B 500 500
高橋 B 500 500

社員ごとの行を維持したまま、部署平均という集計値を付与できる。

3. 使い分けの判断基準

Q1. 明細行(個々のレコード)を残す必要があるか?
  ├─ NO  → GROUP BY(集計表・サマリーレポート)
  └─ YES → Q2へ

Q2. 順位付け・累計・前後比較が必要か?
  ├─ YES → ウィンドウ関数
  └─ NO  → スカラサブクエリでも代替可(ただし性能面でウィンドウ関数が有利なことが多い)

具体的なシーン別の対応表:

やりたいこと 適した手法
部署別の合計・平均だけ欲しい GROUP BY
社員一覧に部署平均も並べて出したい ウィンドウ関数
各部署のTOP3社員を抽出したい ウィンドウ関数(RANK等)
月別売上合計の一覧 GROUP BY
日次売上と累計売上を同時に見たい ウィンドウ関数(フレーム指定)
カテゴリ別の商品数を数えたい GROUP BY

4. 両方を組み合わせるケース

GROUP BYで集約した結果に対して、さらにウィンドウ関数でランキングを付けることも可能です。

SELECT
    department,
    total_salary,
    RANK() OVER (ORDER BY total_salary DESC) AS dept_rank
FROM (
    SELECT department, SUM(salary) AS total_salary
    FROM employees
    GROUP BY department
) AS dept_summary;

「部署別の給与合計を出し、その合計額で部署にランキングを付ける」といった二段階の要件は、GROUP BYとウィンドウ関数の併用で実現します。

5. まとめ

判断軸 GROUP BY ウィンドウ関数
行が減ってよいか 減ってよい 減ってはいけない
目的 サマリー生成 ランキング・累計・比較分析
SQLの実行順序上の位置 WHERE後、HAVING前に評価 SELECT句評価時(WHERE/GROUP BYより後)

豆知識: SQLの論理的な実行順序は
FROM → WHERE → GROUP BY → HAVING → SELECT(ウィンドウ関数はここ) → ORDER BY です。
ウィンドウ関数の結果に対してさらにWHEREで絞ることはできず、絞りたい場合はCTEやサブクエリで一段階分ける必要があります。

さいごに

「行を減らしたいか、維持したいか」という一点で考えると、GROUP BYとウィンドウ関数の選択に迷わなくなります。次回はUNIONについて解説します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?