情報処理試験を勉強していると、「HAVING句って何?WHERE句と何が違うの?」と混乱しがちです。この記事では、HAVING句の定義・WHERE句との違い・SQLでの記述ルールを、日常の例え話と図解で整理します。

対象試験と出題頻度

HAVING句は、基本情報技術者・応用情報技術者で出題されるテーマです。

SQLSELECT文に関する穴埋め問題や実行結果を選ぶ問題で、GROUP BY句とセットで問われるのが定番です。

詳細をクリックして確認
対象試験:
基本情報技術者
応用情報技術者
出題頻度:
★★★★☆
ランクA(重要)必ず覚えておくべき

用語の定義

HAVING句とは、一言で言うと

 「GROUP BYでグループ化した結果に対して、集約関数を使った条件で絞り込むためのSQL句

のことです。

イメージとしては、クラスごとの平均点を出した後に、”平均80点以上のクラスだけ表彰する”というフィルターです。

テストの点数を生徒ごとに見て「80点以上の生徒だけ対象にする」のがWHERE句の役割。

一方、クラス単位で平均を出した後に「平均80点以上のクラスだけ残す」のがHAVING句の役割です。

HAVING句の基本情報

項目 内容
分類 SELECT文を構成する句の1つ
役割 GROUP BYでまとめたグループに対して条件を指定し、条件を満たすグループだけを抽出する
記述位置 GROUP BYの直後、ORDER BYの前
条件に使えるもの 集約関数(COUNT, SUM, AVG, MAX, MIN)またはGROUP BYに指定した列

解説

SELECT文には「WHERE → GROUP BY → HAVING → ORDER BY」という処理の流れがあります。

WHERE句で行を絞った後にGROUP BY句でグループ化し、その集計結果をさらにふるいにかけるのがHAVING句の仕事です。

WHERE句との決定的な違い

最も重要なのは「いつ絞り込むか」の違いです。ここだけは確実に押さえてください。

比較項目 WHERE句 HAVING句
絞り込み対象 個々の行(レコード) グループ化後のグループ
実行タイミング GROUP BYの GROUP BYの
集約関数の使用 使用不可 使用可(AVG, COUNT等)

WHERE句に「AVG(点数) >= 80」のような集約関数を書くと構文エラーになります。

集約関数による条件は必ずHAVING句に書くというのが鉄則です。

図解:SELECT文の処理順序とHAVING句の位置

DBMSがSELECT文を処理する順番を図で確認します。HAVING句は4番目に処理されます。

SELECT文の実行順序 ― DBMSは上から順に処理する

FROM どの表からデータを取るか決める
WHERE 条件に合わないを除外する
GROUP BY 指定列の値が同じ行をまとめる
HAVING 条件に合わないグループを除外する ← ここが本記事のテーマ
SELECT 必要な列を取り出す・集計する
ORDER BY 結果を並べ替える

コードではSELECTを最初に書くが、DBMSの処理はFROMから始まる。この違いが穴埋め問題で狙われる。

具体例:得点テーブルでの動作

以下の「得点」テーブルを使って、HAVING句の動作を確認します。

得点テーブル

学生番号 科目 点数
S001 数学 90
S001 英語 70
S002 数学 85
S002 英語 80
S003 数学 60
S003 英語 65

「学生ごとの全科目平均が80点以上の学生」を抽出するSQL文は次のようになります。

SELECT   学生番号, AVG(点数) AS 平均点
FROM     得点
GROUP BY 学生番号
HAVING   AVG(点数) >= 80

このSQL文の処理を順番に追うと、次のようになります。

処理の流れ

STEP 1:FROM 得点テーブル全6行を取得

STEP 2:GROUP BY 学生番号 学生ごとに3グループに分割

 S001グループ(90, 70)→ 平均80 / S002グループ(85, 80)→ 平均82.5 / S003グループ(60, 65)→ 平均62.5

STEP 3:HAVING AVG(点数) >= 80 平均80以上のグループだけ残す

 S001(平均80)→ 残る / S002(平均82.5)→ 残る / S003(平均62.5)→ 除外

STEP 4:SELECT 結果を出力

学生番号 平均点
S001 80
S002 82.5
詳細解説:WHEREで代用できないケースを確認する

仮に上のSQL文のHAVINGをWHEREに置き換えて次のように書いたとします。

SELECT   学生番号, AVG(点数) AS 平均点
FROM     得点
WHERE    AVG(点数) >= 80  -- ← 構文エラー!
GROUP BY 学生番号

WHEREは行単位で動作するため、集約関数(AVG, COUNT等)を条件に指定できません。DBMSはWHEREの処理時点ではまだグループ化を行っていないので、「平均」という概念が存在しないためです。

さらに、構文の記述順として「GROUP BYの後にWHEREを書く」こと自体が文法違反になります。正しい記述順はWHERE → GROUP BY → HAVINGです。

では、この構文が試験でどのように出題されるか見ていきましょう。

HAVING句の核心を3行で

・GROUP BY後のグループに対して集約関数で条件を絞る句
・WHERE句は行単位(グループ化前)、HAVING句はグループ単位(グループ化後)
・集約関数を条件に使えるのはHAVINGだけ。WHERE句に書くと構文エラー


試験ではこう出る!

HAVING句はFE・APの午前(科目A)問題で、GROUP BY句とのセット出題が定番化しています。出題パターンは大きく2つです。

過去問での出題実績

試験回 出題内容 問われたポイント
FE R1秋
午前 問26
「得点」表から学生ごとの平均点が80点以上の学生を抽出するSQL文の空欄補充 ・GROUP BY 学生番号 + HAVING AVG(点数) >= 80 が正解
・「GROUP BY 科目」や「WHERE 点数 >= 80」がひっかけ
AP H31春
午前 問28
「試験結果」表から2018年度の平均点数が600点以上のクラスを取得するSQL文を選択 ・WHERE句で年度を絞った後にGROUP BY + HAVINGで集計条件を指定する順序
・HAVINGに集約関数でない列を書いた選択肢が構文エラーになる点
FE H28春
午後 問3
遊園地の入園情報を管理する関係データベースで、GROUP BY → HAVINGを含むSQL文の空欄補充 ・午後問題でもGROUP BY+HAVING構文は頻出
・会員番号と会員名でグループ化後に抽出条件を指定する流れ

IPA試験での出題パターン

パターン1:「SQL文の空欄を埋めよ」(最頻出)
テーブル定義と目的(「○○ごとの平均が△△以上のものを取得」)が示され、GROUP BY句の対象列とHAVING句の条件式を組み合わせた正しい選択肢を選ぶ形式。ひっかけとして「GROUP BYの後にWHEREを書いた選択肢(構文エラー)」や「GROUP BYの列を間違えた選択肢」が混ぜられる。

 

パターン2:「正しい結果を選べ」
テーブルのデータとSQL文が提示され、HAVING句による絞り込み後の結果表を選ぶ形式。手を動かして各グループの集計値を計算し、条件に合うグループだけを残す作業が必要になる。

 

試験ではここまででOKです。HAVING句に指定できる条件の詳細なルール(GROUP BY列か集約関数のみ)まで覚えておけば、選択肢を消去法で絞れます。


【確認テスト】理解度チェック

ここまでの内容を理解できたか、簡単なクイズで確認してみましょう。


Q. 「売上」表に対して次のSQL文を実行したとき、HAVING句の役割として最も適切な説明はどれか。

SELECT   商品名, SUM(金額) AS 合計金額
FROM     売上
WHERE    売上日 BETWEEN '2024-01-01' AND '2024-12-31'
GROUP BY 商品名
HAVING   SUM(金額) >= 100000
  • A. 売上日が2024年の行だけを個別に抽出し、金額が10万円以上の行を返す。
  • B. 売上表の全行を商品名ごとにグループ化した後、商品名を昇順で並べ替える。
  • C. 商品名ごとにグループ化した後、合計金額が10万円以上のグループだけを抽出する。

正解と解説を見る

正解:C

解説:
HAVING句は、GROUP BYでグループ化された後のグループに対して集約関数による条件を適用する句です。このSQL文では、商品名ごとにグループ化した上で、SUM(金額)が10万円以上のグループだけを結果として返します。

選択肢Aは、WHERE句の役割を述べています。WHERE句が「2024年の行を抽出」する部分を担っていますが、「金額が10万円以上の行」という表現は個々の行に対する条件であり、HAVING句が行うグループ単位の集計条件とは異なります。選択肢Bは、ORDER BY句の機能(並べ替え)を混同しています。HAVING句にソート機能はありません。


よくある質問(FAQ)

Q. HAVING句はGROUP BY句なしで使えますか?

SQL標準の規格上はGROUP BYなしでHAVINGを書くことも文法違反ではありません。その場合、テーブル全体が1つのグループとして扱われます。ただし、実務でもIPA試験でもGROUP BYとセットで使うのが通常です。GROUP BYなしのHAVING句が出題された実績はないため、「HAVING句はGROUP BYの後に書くもの」と覚えておけば十分です。

Q. HAVING句にGROUP BYで指定していない列は書けますか?

書けません。HAVING句に指定できるのは、GROUP BY句で指定した列か、集約関数(COUNT, SUM, AVG, MAX, MIN)のいずれかです。AP H31春 午前問28では、HAVING句にグループ化されていない「点数」列を直接指定した選択肢が構文エラーとして不正解になっています。この制約を知っていれば、選択肢の消去に使えます。

Q. WHERE句とHAVING句の両方に条件を書くケースはありますか?

あります。実際にAP H31春 午前問28がまさにそのパターンです。「WHERE句で2018年度の行に絞る → GROUP BYでクラスごとにまとめる → HAVINGで平均600点以上のクラスだけ残す」という流れで、両方の句がそれぞれ別の役割で条件を指定しています。WHERE句で先に不要な行を除外し、HAVING句で集計後の条件を適用するのが正しい組み合わせです。

Q. 実務ではHAVING句はどんな場面で使いますか?

売上データの分析が代表例です。「月ごとの売上合計が100万円以上の月だけ抽出したい」「顧客ごとの注文回数が5回以上のリピーターだけ一覧にしたい」といった、集計結果に基づくフィルタリングが必要な場面で使います。BIツールやレポート生成の裏側でも、GROUP BY + HAVINGのSQL文が自動生成されていることが多いです。