【初心者向け】SQLのHAVING と WHERE の違いを整理する(GROUP BYとの関係も解説)
はじめに
SQLでデータを抽出するとき、WHERE 句を使って条件を指定するのはよく知られています。
一方で、HAVING という似たような構文があることを知り、次のように戸惑ったことはありませんか?
「
WHEREとの違いは何?」
「どちらに条件を書けばよいのか分からず、迷う」
「GROUP BYとセットでないと使えないのか?」
私自身も最初は混乱していましたが、実はこの2つは条件を適用するタイミングが異なるだけです。
本記事では、初心者の方に向けて HAVING と WHERE の違いを、GROUP BY の関係性にも触れながら整理します。
1. 結論:WHERE は「集計前」、HAVING は「集計後」
| 句 | 使うタイミング | 主な用途 |
|---|---|---|
WHERE |
データを グループ化する前 に絞り込む | 行データの条件指定(例:price > 1000) |
HAVING |
データを グループ化した後 に絞り込む | 集計結果の条件指定(例:SUM(price) > 1000) |
2. 例で比較
テーブル:orders
| id | user_id | amount |
|---|---|---|
| 1 | 1 | 5000 |
| 2 | 1 | 3000 |
| 3 | 2 | 2000 |
| 4 | 2 | 1000 |
| 5 | 3 | 400 |
WHERE を使う例:1件ごとの注文が 1000円以上のデータだけを対象にする
SELECT user_id, SUM(amount) AS total_amount
FROM orders
WHERE amount >= 1000
GROUP BY user_id;
| user_id | total_amount |
|---|---|
| 1 | 8000 |
| 2 | 3000 |
WHERE は GROUP BY の前に実行されるので、まずは amount >= 1000 を満たす行だけが集計対象になります。
HAVING を使う例:集計した合計が 5000円以上のユーザーを抽出する
SELECT user_id, SUM(amount) AS total_amount
FROM orders
GROUP BY user_id
HAVING SUM(amount) >= 5000;
| user_id | total_amount |
|---|---|
| 1 | 8000 |
この場合は、全ての注文を集計したあとで SUM(amount) を見て絞り込んでいるため、
user_id = 1 だけが条件に該当します。
3. HAVING は GROUP BY なしでも使える
実は HAVING は、GROUP BY を使わなくても書くことができます。
SELECT COUNT(*) FROM orders
HAVING COUNT(*) > 3;
このように、集計関数だけを使って結果が1行になる場合には、HAVING を使ってその結果に対して条件を付けることが可能です。
ただし、こうした使い方はあまり一般的ではなく、
HAVING は基本的に GROUP BY とセットで使うものとして覚えておいたほうが混乱しにくいでしょう。
4. 使い分けの目安
| 目的 | 書く場所 |
|---|---|
| テーブルの各行(レコード)に対して条件をかけたいとき | WHERE |
GROUP BY でまとめた集計結果に条件をかけたいとき |
HAVING |
おわりに
HAVING と WHERE はとても似ていますが、「どの段階で絞り込むか」 が最大の違いです。
WHERE:グループ化前に絞るHAVING:グループ化後に絞る
この違いを理解しておくことで、実務でも迷わず使い分けやすくなります。
GROUP BY とセットで登場する場面も多いので、合わせて理解を深めておくのがおすすめです。
本記事が理解の一助になれば幸いです。
📚 関連記事:【SQL】GROUP BY と集計関数の使い方を整理する
Discussion