SQL練習室
← SQLガイド

SQLのHAVINGとは?集計結果の絞り込みとWHEREの違いを解説

HAVINGは、集計した結果を条件で絞る構文です。「社員が2人以上いる部署」のように、数えてから判断する条件に使います。まず全部署の集計を見て、条件を付けるとどの部署が残るかを確認しましょう。

例で使う表

employeesの1行が社員1人分です。営業が2人、開発が2人、サポートが1人います。salaryは月給(円)で、恵比寿さんのNULLは月給が未入力であることを表し、0円とは区別します。すべての例でこの5人を使います。結果表の行の並びは一例です。ORDER BYで指定しない限り、表示順は保証されません。

employees:社員5人の一覧(salaryは月給・円)
id(社員ID)name(名前)department(部署)salary(月給)
1青木営業300000
2北野開発400000
3中央営業350000
4大和開発400000
5恵比寿サポートNULL

HAVINGの基本構文

sql
SELECT department, COUNT(*) AS people
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;

まずGROUP BYで全部署の人数を確認する

HAVINGを付ける前に、部署ごとの人数を出します。営業2人、開発2人、サポート1人の3行です。この集計結果を出発点に、次の節で「2人以上」という条件を付けます。

sql
SELECT department, COUNT(*) AS people
FROM employees
GROUP BY department;
実行結果
departmentpeople
サポート1
営業2
開発2

HAVING COUNTで2人以上の部署を選ぶ

GROUP BYの後ろにHAVING COUNT(*) >= 2を足します。集計した人数を比べるので、営業と開発が残り、1人のサポートは外れます。WHERE COUNT(*) >= 2とは書けません。集計結果を条件にする場所がHAVINGです。

sql
SELECT department, COUNT(*) AS people
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;
実行結果
departmentpeople
営業2
開発2

HAVING SUMで月給の合計が70万円以上の部署を選ぶ

人数ではなく月給の合計を条件にするにはSUM(salary)を使います。営業は650000円、開発は800000円なので、開発だけが残ります。個人の月給が700000円以上かどうかではなく、部署全体の合計を比べています。

sql
SELECT department, SUM(salary) AS total_salary
FROM employees
GROUP BY department
HAVING SUM(salary) >= 700000;
実行結果
departmenttotal_salary
開発800000

WHEREで月給35万円以上の社員だけを集計する

WHEREとHAVINGの違いを見るため、まずWHEREだけを使います。集計前に社員を絞るので、営業の青木さんは外れます。残った中央さんで営業1人、北野さんと大和さんで開発2人になります。

sql
SELECT department, COUNT(*) AS people
FROM employees
WHERE salary >= 350000
GROUP BY department;
実行結果
departmentpeople
営業1
開発2

WHEREとHAVINGを組み合わせる

前の結果にHAVING COUNT(*) >= 2を加えます。月給35万円以上の社員だけをWHEREで選び、その人数が2人以上の部署をHAVINGで残します。営業は1人になっているため外れ、開発だけが表示されます。

sql
SELECT department, COUNT(*) AS people
FROM employees
WHERE salary >= 350000
GROUP BY department
HAVING COUNT(*) >= 2;
実行結果
departmentpeople
開発2

ANDで集計結果の条件を2つ指定する

人数が2人以上で、平均月給も350000円以上の部署を選びます。営業は2人ですが平均325000円なので外れます。開発は2人、平均400000円で両方を満たします。SELECTに判定に使う値を出すと、残った理由を確認できます。

sql
SELECT department, COUNT(*) AS people,
  AVG(salary) AS average_salary
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2
  AND AVG(salary) >= 350000;
実行結果
departmentpeopleaverage_salary
開発2400000

実際に1問解いてみる

HAVING COUNT

社員が2人以上の部署と人数をdepartment、COUNT(*)の順で取得してください。行順は問いません。

テーブル

読み込み中…

実行結果

関連構文

HAVINGについてよくある質問

GROUP BYなしでもHAVINGは使えますか?
使えます。表全体を1つのグループと見なします。今回の表でSELECT COUNT(*) FROM employees HAVING COUNT(*) >= 5;なら5を含む1行が返り、条件を>= 6にすると0行になります。
平均がNULLの部署は比較条件に残りますか?
AVG(salary) >= 350000のような比較では残りません。月給が全員未入力の部署を探すなら、HAVING AVG(salary) IS NULLで判定します。

参考文献

内容はPostgreSQL公式ドキュメントを参照し、初めて学ぶ人向けに日本語で整理しています。