章: 第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の基本」 を学びます。複雑な条件を段階的に組み立て、可読性と保守性を両立する書き方を確認します。