WHERE と HAVING の違いは何ですか

集計する前の行を絞るのが WHERE、集計したあとのまとまりを絞るのが HAVING。SQL が動く順で答えます。

こう聞かれます

  • 「WHERE と HAVING の違いは何ですか」
  • 「支払い済みの注文だけで、合計が 5000 円以上の顧客を出すなら、どう書きますか」
  • 「WHERE に SUM を書くとエラーになるのはなぜですか」

面接官が見ている点

  • 「集計の前か後か」で区別できるか
  • SQL が書いた順ではなく、決まった順で動くと分かっているか
  • 1 つの問いの中で、WHERE と HAVING を両方使い分けられるか

短い答え

  • WHERE は集計する前の 1 行ずつを絞り、HAVING は GROUP BY でまとめたあとのまとまりを絞ります。
  • SQL は、表を読む、WHERE で絞る、GROUP BY でまとめる、HAVING で絞る、の順で動きます。
  • そのため合計や件数を使う条件は HAVING に、1 行ずつで決まる条件は WHERE に書きます。

少し詳しい答え

両方を使う例

支払い済みの注文だけで顧客ごとに合計し、5000 円以上の人を出します。

SQL クエリ

CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  customer VARCHAR(20),
  status VARCHAR(10),
  amount INTEGER
);
INSERT INTO orders VALUES
  (1, 'Aya', 'paid', 3000),
  (2, 'Aya', 'paid', 4000),
  (3, 'Ken', 'paid', 2000),
  (4, 'Ken', 'unpaid', 9000);
SELECT customer, SUM(amount)
FROM orders
WHERE status = 'paid'
GROUP BY customer
HAVING SUM(amount) >= 5000
ORDER BY customer;
Aya|7000

Ken さんは、未払いの 9000 円が WHERE で先に除かれるので、合計が 2000 円になり、HAVING で落ちます。WHERE を外すと、結果が変わります。

SQL クエリ

SELECT customer, SUM(amount)
FROM orders
GROUP BY customer
HAVING SUM(amount) >= 5000
ORDER BY customer;
Aya|7000
Ken|11000

動く順

SQL は書いた順ではなく、おおむね FROM、WHERE、GROUP BY、HAVING、SELECT、ORDER BY の順で動きます。WHERE が動く時点では、まだまとめていないので、合計はありません。だから WHERE SUM(amount) >= 5000 はエラーになります。

1 行ずつで決まる条件は、HAVING に書いても結果が同じになる場合があります。それでも WHERE に書くと、まとめる前に行が減るので、無駄な集計をしなくて済みます。

作った物と結べると伝わりやすくなります。たとえば「学習記録のアプリで、今月の記録だけを WHERE で絞り、学習時間の合計が 10 時間を超えた人を HAVING で出した」のように話します。

よくある間違い

  • 「HAVING は GROUP BY 用の WHERE」とだけ言う間違いではありませんが、集計の前か後か、という動く順まで言うと伝わります
  • 1 行ずつの条件まで HAVING に書く結果が同じでも、まとめる前に減らせる行を残したまま集計することになります
  • WHERE で除いた行が、集計に入ると思う WHERE で除いた行は、合計にも件数にも入りません。この例の Ken さんの合計が 2000 円になるのはそのためです

深掘りの問い

  • 「SELECT で付けた別名を WHERE で使えますか」 使えません。WHERE は SELECT より先に動くので、別名はまだありません
  • 「GROUP BY を書かずに HAVING を使うと、どうなりますか」表全体を 1 つのまとまりとして扱い、その合計などで絞る、と答えます
  • 「件数が 0 の顧客も出したいときは」顧客の表から LEFT JOIN して数える、と答えます。注文の表だけをまとめても、注文の無い人は出てきません

確認日 2026年10月23日

技術面接問題の一覧へ戻る