3秒でわかる
SQL は書いた順ではなく FROM から評価される。順番を知れば別名が使えない理由も WHERE と HAVING の違いも説明でき、遅い原因も追える。
もう少し詳しく
どういうものか
SQL の各句がデータベース内部で処理される順番のことです。人間は SELECT から書き始めますが、実際の評価は FROM で対象のテーブルを決めるところから始まります。標準的な SELECT 文では FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT の順に進みます。
つまり SELECT で付けた列の別名は、SELECT より前に動く WHERE や GROUP BY からは見えません。逆に SELECT の後に動く ORDER BY からは見えます。この一点だけでも、初学者が出す SQL エラーのかなりの部分を説明できます。
なぜ必要か
書いた順と動く順が違うことを知らないと、エラーメッセージが理不尽に見えます。「同じ別名なのに ORDER BY では通って WHERE では Unknown column になる」という現象は、順番を知っていれば当たり前の話ですが、知らなければ当てずっぽうで書き直すしかありません。
性能面でも効きます。LIMIT 10 と書いたから 10 行しか読んでいない、という思い込みはよくある誤解で、実際は ORDER BY が全行を並べ替えてから先頭 10 行を切り出します。どの段階で行数が減るのかを把握できると、インデックスを張る列の見当も付きます。
具体例
SELECT department, COUNT(*) AS member_count
FROM employees
WHERE hire_date >= '2020-01-01'
GROUP BY department
HAVING COUNT(*) >= 3
ORDER BY member_count DESC
LIMIT 5;このクエリは employees 全体から 2020 年以降の入社者だけを残し (WHERE)、部署ごとにまとめ (GROUP BY)、3 人以上のグループだけを残し (HAVING)、そこでようやく列を選び (SELECT)、人数の多い順に並べて (ORDER BY) 上位 5 件を返します。HAVING で member_count という別名が使えず COUNT(*) と書き直しているのは、HAVING が SELECT より先に動くためです。
つまずきやすいところ
似た用語との違い
| 句 | 動くタイミング | 絞り込む対象 |
|---|---|---|
| WHERE | GROUP BY の前 | 集計前の 1 行ずつ |
| HAVING | GROUP BY の後 | 集計してできたグループ |
覚え方
「FROM で集めて、WHERE で捨てて、GROUP でまとめて、HAVING でまた捨てて、最後に SELECT で見せる」と口に出して覚えると、別名が見える範囲も自然に思い出せます。