こう 聞かれます
- 「WHERE と HAVING の
違いは 何ですか」 - 「支払い
済みの 注文だけで、 合計が 5000 円以上の 顧客を 出すなら、 どう 書きますか」 - 「WHERE に SUM を
書くと エラーに なるのは なぜですか」
面接官が 見ている点
- 「集計の前か後か」で
区別できるか - SQL が
書いた 順ではなく、 決まった 順で 動くと 分かっているか - 1 つの
問いの 中で、 WHERE と HAVING を 両方使い分けられるか
短い答え
- WHERE は
集計する 前の 1 行ずつを 絞り、 HAVING は GROUP BY で まとめた あとのまとまりを 絞ります。 - SQL は、
表を 読む、 WHERE で 絞る、 GROUP BY で まとめる、 HAVING で 絞る、の順で 動きます。 - その
ため合計や 件数を 使う 条件は HAVING に、 1 行ずつで 決まる 条件は WHERE に 書きます。
少し 詳しい答え
両方を使う例
支払い
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|7000Ken さんは、
SQL クエリ
SELECT customer, SUM(amount)
FROM orders
GROUP BY customer
HAVING SUM(amount) >= 5000
ORDER BY customer;Aya|7000
Ken|11000動く順
SQL はWHERE SUM(amount) >= 5000 は
1 行ずつで
作った
よく ある間違い
- 「HAVING は GROUP BY 用の WHERE」とだけ言う
間違いでは ありませんが、 集計の 前か 後か、という 動く 順まで 言うと 伝わります - 1 行ずつの
条件まで HAVING に書く 結果が 同じでも、 まとめる 前に 減らせる 行を 残したまま 集計する ことになります - WHERE で
除いた 行が、 集計に 入ると思う WHERE で 除いた 行は、 合計にも 件数にも 入りません。 この 例の Ken さんの 合計が 2000 円に なるのは そのためです
深掘りの問い
- 「SELECT で
付けた 別名を WHERE で 使えますか」 使えません。 WHERE は SELECT より 先に 動くので、 別名は まだ ありません - 「GROUP BY を
書かずに HAVING を 使うと、 どうなりますか」 表全体を 1 つの まとまりとして 扱い、 その合計などで 絞る、と答えます - 「件数が 0 の
顧客も 出したいときは」顧客の 表から LEFT JOIN して 数える、と 答えます。 注文の 表だけを まとめても、 注文の 無い 人は 出てきません