基本情報技術者試験 (FE) 科目 A — データベース

GROUP BY と HAVING — WHERE との違い

定義

GROUP BY は指定した列の値が等しい行を 1 つのグループにまとめ、集約関数はグループごとに計算される。HAVING はグループに対する絞り込みで、行に対する絞り込みである WHERE より後に評価される。

GROUP BY は行をグループにまとめる

集約関数は 表全体を 1 つの値にまとめました。GROUP BY を付けると、指定した列の値が同じ行ごとに集計されます。

SELECT 部門コード, COUNT(*), AVG(給与)
FROM 従業員
GROUP BY 部門コード

部門コードが同じ行が 1 グループになり、グループの数だけ結果の行ができます

試す: GROUP BY を消すと 1 行にまとまる

リセットで表の中身も元に戻ります
エディタを読み込み中…

HAVING はグループを絞り込む

「2 人以上いる部門だけ」のように、集計した結果で絞り込みたいときに HAVING を使います。

GROUP BY 部門コード
HAVING COUNT(*) >= 2

試す: HAVING の条件を >= 3 にすると残るグループが減る

リセットで表の中身も元に戻ります
エディタを読み込み中…

WHERE と HAVING の違いは「評価順」で決まる

この 2 つの違いは、暗記ではなく評価順で理解できます。

  1. FROM — 表を読み込む
  2. WHERE1 行ずつ絞り込む
  3. GROUP BY — 残った行をグループにまとめる
  4. HAVINGグループ単位で絞り込む
  5. SELECT — 列を取り出す

WHERE は 2 番目、グループができるのは 3 番目です。 つまり WHERE の時点ではまだグループが存在しないので、WHERE COUNT(*) > 1 は書けません。これが理由のすべてです。

逆に「D01 部門の中で平均を出したい」のようにグループ化する前に行を減らすのは WHERE の仕事です。 両方書くこともできます。

試す: HAVING の条件を WHERE に移すとエラーになる

リセットで表の中身も元に戻ります
エディタを読み込み中…

GROUP BY に無い列は取り出せない

SELECT 氏名, COUNT(*) FROM 従業員 GROUP BY 部門コード
-- エラー: 氏名 は GROUP BY に無い

D01 部門には青木・井上・上田の 3 人がいます。 このグループの「氏名」はどれを出せばよいか決まりません。 だから標準 SQL ではエラーになります。

一部のデータベース製品は黙って通してしまいますが、試験では誤りです。この実行シミュレーターも 標準 SQL に合わせてエラーにしています。

試す: このままだとエラー。氏名 を MAX(氏名) にするか GROUP BY に足すと通る

リセットで表の中身も元に戻ります
エディタを読み込み中…

グループの集合として見る

一つ進めるを押してください。GROUP BY の段階で、行の集合ではなくグループの集合が表示されます。 HAVING がそのグループをどう減らすかも次の段階で見えます。 WHERE と HAVING の違いが一番はっきり分かる場所です。

試す: 一つ進める で GROUP BY と HAVING の段階を見比べる

リセットで表の中身も元に戻ります
エディタを読み込み中…

試験で問われるポイント

  • WHERE と HAVING のどちらに書くか。最頻出です
  • 結果が何行になるか=グループがいくつできるか
  • GROUP BY に無い列を SELECT に書いた選択肢は誤りだと見抜けること
  • WHERE と HAVING を両方書いたときの評価順

よくある疑問

Q.WHERE と HAVING はどう使い分けますか?
A.WHERE は 1 行ずつの絞り込み、HAVING はグループ単位の絞り込みです。評価順が WHERE → GROUP BY → HAVING なので、WHERE の時点ではまだグループが存在せず、集約関数も使えません。「集約した結果で絞る」なら HAVING です。
Q.GROUP BY に書いていない列を SELECT に書けないのはなぜですか?
A.1 つのグループに複数の行がまとまるため、その列のどの行の値を出すべきかが決まらないからです。標準 SQL ではエラーになります(一部の製品は黙って通しますが、試験では誤りです)。GROUP BY に加えるか、MAX などの集約関数で包んでください。
Q.GROUP BY を書かずに集約関数だけを書いたらどうなりますか?
A.表全体が 1 つのグループとして扱われ、結果は 1 行になります。該当する行が 0 件でも 1 行返る(COUNT は 0)点に注意してください。

GROUP BY と HAVING」の練習問題 2

読んだ内容がそのまま出題されます。解答すると解説と、 その SQL を実行シミュレーターで開くリンクが出ます。

自由に試す / 他のレッスンを読む

データベース分野をもっと学ぶ(おすすめ書籍)

本セクションはAmazonアソシエイトのリンクを含みます。

オンライン個別指導

プログラムの読み方でつまずいたら。

たいてっくが、アルゴリズムの追い方から SQL・データベース設計まで、1対1で学習をサポートします。「コードを目で追っても何をしているか分からない」段階からで大丈夫です。まずは無料相談から。

無料相談を予約する →
受講者の声 (DB・SQL コース)
menta レビュー原文を見る →
  • 教え方も上手で、お人柄も良いメンターです。DB周りの知識はもちろん、何より、しっかり教えてあげようという姿勢がとてもありがたかったです。データベース、SQLの学習を考えている方にはおススメです。
    H 様DB・SQL コース受講
  • 体系的に知識を教えてくださり、実際の業務でも大変役立っております。特に短い時間で効率よく知識の習得や、練習をできているのは期待以上でした。
    M 様DB・SQL コース受講
  • 大変充実したコンテンツでわかりやすいご説明をありがとうございました。基本的な質問にも丁寧にご説明いただき、また業務のご相談にも乗って頂き大変有意義な時間でした。
    K 様DB・SQL コース受講