FE EXAM

HAVING句(集計結果の条件)

グループ化した集計結果に対して条件を指定するSQLの句。

INTERACTIVE VISUALIZATION
WHERE除外
HAVING除外
フェーズ
idle
絞り込む対象
残るグループ数
シナリオ
ステップ1 / 6
STEP 1/6元の表を確認するこれは社員の給与表(給与は万円)です。「社員が2人以上いる部署だけ、その平均給与を出したい」とします。WHERE では1行ずつしか条件をかけられないため、「部署の人数」という集計結果に対する条件は HAVING で指定します。まずは元データの状態です。
employeesdeptnamesalary営業Aoki30営業Endo36開発Kato44開発Sato48開発Ueda40総務Wada38
SQL
SELECT dept, COUNT(*), AVG(salary)
FROM employees
GROUP BY dept
HAVING COUNT(*) >= 2
解説

📌
HAVING句とは

集計後のグループ営業 2人開発 3人総務 1人HAVINGCOUNT>=2条件を満たす分営業 2人開発 3人総務は除外

HAVING句とは、GROUP BY でグループ化・集計したあとの結果に対して条件を指定し、条件に合うグループだけを残すためのSQLの句です。「件数が○件以上のグループだけ」「平均が○以上の部署だけ」といった絞り込みに使います。

身近な例で考えると、クラスごとの平均点を出したあとで「平均80点以上のクラスだけ表彰する」という選び方に似ています。一人ひとりではなく、集計したクラス単位の値を見て選ぶのがポイントです。

上のツールで▶ボタンを押すと、グループ化して集計したあと、HAVING の条件によってグループが残ったり除外されたりする様子を確認できます。

⚖️
WHEREとの違い

どちらも「条件で絞り込む」点は同じですが、効くタイミングと対象が違います。

項目WHEREHAVING
効くタイミング集計の前集計の後
絞る対象1行ずつグループ(集計値)
集計関数使えない使える(COUNT等)

例えば「給与30万円未満の人を除いて集計したい」なら WHERE salary >= 30、「集計した平均が40以上の部署だけ残したい」なら HAVING AVG(salary) >= 40 です。WHERE には COUNT や AVG などの集計関数を書けない、という点も大きな違いです。上のツールの「WHEREとHAVINGの併用」シナリオで両方の動きを見比べられます。

🔻
集計後の絞り込み

WHERE行を絞るGROUP BYまとめる集計COUNT等HAVING群を絞る

SQL を書く順番(SELECT…FROM…WHERE…GROUP BY…HAVING…ORDER BY)と、実際に処理される順番は違います。データベースは内部的に次の順で処理します。
① WHERE:集計前に1行ずつ絞り込む
② GROUP BY:同じ値の行をグループにまとめる
③ 集計:各グループで COUNT・AVG などを計算
④ HAVING:集計結果のグループを条件で絞る

HAVING は「集計が終わってはじめて分かる値(件数・合計・平均など)」に条件をかけるので、必ず集計のあとに働きます。だからこそ COUNT(*) や AVG(salary) のような集計関数を条件式に書けるのです。上のツールの最終ステップで、集計後にグループが絞り込まれて結果が確定する流れを確認してください。

🔗
WHEREとHAVINGを組み合わせる

全行給与いろいろ部署いろいろ人数いろいろWHEREsalary>= 30低給与行を除去GROUP部署ごとにまとめCOUNT集計HAVINGCOUNT>= 2小グループを除去

WHERE と HAVING は同じ SQL の中で一緒に使えます。それぞれが別のタイミングに働くので、役割が重なりません。

例えば「給与30万円未満の人を最初に除いてから残った人で部署ごとに集計して、2人以上の部署だけ表示する」という2段階の絞り込みができます。
WHERE salary >= 30:まず低給与の行を集計対象から外す(個人レベル)
HAVING COUNT(*) >= 2:集計後に人数の少ない部署を除く(グループレベル)

なぜ分けるかというと、WHERE で除いた行は集計にも含まれないからです。給与30万未満の人を先に除けば、その人たちは COUNT にも AVG にも入りません。この2つを組み合わせると「誰を集計対象にするか」と「どのグループを最終結果に残すか」を別々に制御できます。上のツールの「WHEREとHAVINGの併用」シナリオで確認してください。

📊
HAVINGで使う集計関数の種類

集計関数(しゅうけいかんすう)とは、グループ内の複数の値から1つの値を計算する関数です。HAVING の条件式にはこれらを使います。WHEREの条件式には使えないことも合わせて覚えておきましょう。

関数意味使い方の例
COUNT(*)グループの行数HAVING COUNT(*) >= 2
SUM(列)合計値HAVING SUM(salary) > 100
AVG(列)平均値HAVING AVG(salary) >= 40
MAX(列)最大値HAVING MAX(score) >= 90
MIN(列)最小値HAVING MIN(score) >= 60

なぜ WHERE では集計関数が使えないかというと、WHERE が動くタイミングには、まだグループも集計も存在しないからです。「合計がいくつか」はグループを作って計算して初めて分かります。よって、集計した値に条件をかけたいときは必ず HAVING を使います。

練習問題

🎯
基本情報技術者 練習問題

Q1.HAVING句の役割として最も適切なものはどれか。
A.グループ化して集計した結果に対して条件を指定する
B.集計する前に1行ずつ条件で絞り込む
C.結果を指定した列で並べ替える
D.2つの表を結合する
Q2.WHERE句と HAVING句の違いとして正しいものはどれか。
A.WHERE は集計後のグループ、HAVING は集計前の行に条件をかける
B.WHERE は集計前の行、HAVING は集計後のグループに条件をかける
C.WHERE も HAVING もまったく同じ意味である
D.HAVING は GROUP BY なしでは絶対に使えない
Q3.次のSQLで、結果に残る部署として正しいものはどれか。各部署の人数が 営業2人・開発3人・総務1人 のとき。「GROUP BY dept HAVING COUNT(*) >= 2」
A.営業・開発・総務のすべて
B.総務だけ
C.営業と開発
D.結果は空になる

関連コンテンツ