第09回: HAVING句の使い所 — WHEREで書けないなら、HAVINGの出番

章: 第2章: 実務クエリ基礎

「投稿が10件以上あるユーザーだけ抽出したい」——WHEREでできないのはなぜ?

WHERE post_count >= 10 と書きたくなりますが、post_count は集計結果なので WHERE の時点ではまだ存在しません。WHERE はグループ化・集計のに評価されるため、集計後の値を条件にするには別の構文が必要です。

それが HAVING 句です。 GROUP BY の後に評価され、集計関数の結果を条件として絞り込めます。

WHERE と HAVING の使い分けを正確に理解する

WHERE と HAVING を混同すると、パフォーマンスが落ちたり意図しない結果になったりします。判断基準は「集計前か集計後か」の一点です。

WHERE vs HAVING の比較

比較項目 WHERE HAVING
評価タイミング GROUP BY の前(行フィルタ) GROUP BY の後(グループフィルタ)
使える条件 元テーブルのカラム値 集計関数(COUNT, SUM, AVG など)
インデックスの恩恵 受けられる 受けられない(集計後のため)
パフォーマンス WHERE で先に絞ると速い HAVINGだけでは大量グループが発生しうる

チェックポイント: WHERE で絞れる条件は HAVING に書かないようにしましょう。たとえば WHERE status = 'published' を HAVING に書くと、全行をグループ化してから絞るため余分なコストがかかります。WHERE で先に行を減らし、HAVING で集計後の絞り込みに専念するのが正しいパターンです。

実際のコードのサンプル


SELECT user_id, COUNT(*) AS post_count
FROM posts
GROUP BY user_id
HAVING COUNT(*) >= 10;

まとめ & 次のステップ

  • WHERE はグループ化の前に評価される。集計関数は使えない
  • HAVING はグループ化の後に評価される。集計関数の結果で絞り込める
  • WHERE で絞れる条件は必ず WHERE に書く。HAVINGへの誤配置はパフォーマンス劣化につながる
  • HAVING COUNT(*) >= N のパターンは「一定量以上のグループだけ表示する」集計レポートで頻出

次回は 「サブクエリとCTEの基本」 を学びます。複雑な条件を段階的に組み立て、可読性と保守性を両立する書き方を確認します。

Related Articles