SQLのHAVINGとは?WHEREとの違い・複数条件・GROUP BYなしの使い方
HAVINGは、集計したグループを条件で絞る構文です。「2人以上の部署」のように、数えてから判断する条件に使います。WHEREとの違いを押さえ、合計額や複数条件で必要なグループだけを取り出しましょう。
HAVINGの基本構文
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;HAVING COUNTで件数を条件にする
部署ごとの行数を数え、2件以上のグループだけを残します。1人の部署は結果から消えます。集約結果はWHEREの段階ではまだ条件にできないため、WHERE COUNT(*) >= 2とは書けません。
SELECT department, COUNT(*)
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;HAVING SUMで合計額を条件にする
合計給与が100万円以上の部署を選ぶにはSUM(salary)を条件にします。個々の給与が100万円以上というWHERE条件とは別の意味です。HAVINGの集約式をSELECTに出すことは必須ではありませんが、表示すると絞り込みの理由を確認しやすくなります。
SELECT department, SUM(salary)
FROM employees
GROUP BY department
HAVING SUM(salary) >= 1000000;HAVING AVGで平均値を条件にする
AVG(salary) >= 500000なら部署平均が50万円以上の部署を返します。NULLの給与は平均の分母にも含まれません。全員が未入力の部署では平均がNULLになり、この比較を通過しない点に注意しましょう。
SELECT department, AVG(salary)
FROM employees
GROUP BY department
HAVING AVG(salary) >= 500000;WHEREとHAVINGの違い:集計前と集計後
在籍者だけを数え、その人数が2人以上の部署を選ぶなら、在籍条件をWHERE、人数条件をHAVINGに書きます。WHEREによって平均・件数の母集団そのものが変わります。「全社員の人数」と「在籍者の人数」を取り違えないことが大切です。
| 句 | 判定対象 | 例 |
|---|---|---|
| WHERE | 集計前の行 | active = true |
| HAVING | 集計後のグループ | COUNT(*) >= 2 |
SELECT department, COUNT(*)
FROM employees
WHERE active = true
GROUP BY department
HAVING COUNT(*) >= 2;HAVINGの複数条件:AND・ORとカッコ
人数と平均の両方を満たすにはAND、いずれかならORです。WHEREと同じくANDがORより優先されるので、混在するときはカッコで判断のまとまりを示します。まず各集約値をSELECTで表示してから条件を追加すると、意図したグループを残しているか確認できます。
SELECT department, COUNT(*), AVG(salary)
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2
AND (AVG(salary) >= 500000 OR SUM(salary) >= 900000);GROUP BYなしのHAVING:全体を1グループとして判定する
GROUP BYを省くと対象全体が1グループになります。HAVINGがtrueなら集約結果を1行、そうでなければ0行返します。全社人数が基準以上のときだけレポートを出す、といった全体判定に使えます。集計キーがないので、社員名などの明細列はそのまま出せません。
SELECT COUNT(*)
FROM employees
HAVING COUNT(*) >= 5;HAVINGでよくある間違い
SELECTの別名をHAVINGから参照する
PostgreSQLのHAVINGでは同じSELECTの出力別名を参照できません。HAVING people >= 2ではなくCOUNT(*) >= 2と書きます。別名で条件をまとめたい場合はサブクエリに分け、その外側のWHEREを使います。
SELECT department, COUNT(*) AS people
FROM employees
GROUP BY department
HAVING COUNT(*) >= 2;実際に1問解いてみる
HAVING COUNT
社員が2人以上の部署と人数をdepartment、COUNT(*)の順で取得してください。行順は問いません。
テーブル
読み込み中…
実行結果
関連構文
HAVINGについてよくある質問
- HAVINGとWHEREは両方使えますか?
- 使えます。WHEREをGROUP BYより前、HAVINGを後ろに書き、入力行の条件と集約値の条件を分けます。
- HAVINGはSELECTにない集約関数も使えますか?
- 使えます。たとえば部署名だけを表示し、HAVING COUNT(*) >= 2で人数を判定できます。集計値を表示するかと、条件に使うかは別です。
- HAVINGで平均がNULLの部署を探せますか?
- HAVING AVG(salary) IS NULLで探せます。= NULLでは判定できません。グループ化された部署の給与がすべてNULLなら、この条件に一致します。
参考文献
内容はPostgreSQL公式ドキュメントを参照し、初めて学ぶ人向けに日本語で整理しています。
- PostgreSQL公式:GROUP BYとHAVING — 集計単位、集約前後の条件、選択列の制約
- PostgreSQL公式:集約関数 — AVGとBOOL_ANDのNULL処理
- PostgreSQL公式:SELECTリスト — 出力別名を使える句の制約