はじめに
SQLは実行順序を念頭に置いて書かなきゃダメという自戒の念を込めて、記事を執筆してます。。。
休日にネットに落ちてるSQL練習問題をやるます。
SQLの実行順序
まず、はじめにSQLには句毎に実行される順番がある。
SELECT
hoge,hogehoge,hoge2
FROM
A
WHERE
hoge > 3;
まずはこんなSQL文があるとする。
この時、SQLはどの句から実行していくのか?
答えは以下の通り。
FROM句→WHERE句→SELECT句
FROM句で対象のテーブルを絞り、WHERE句でレコードを絞り、SELECT句で列を絞る。
だから、FROM句から実行されていく。
SELECT句から実行してたら、全テーブルのhogeという列を抽出する所から始める訳です。
テーブルを結合した時はどうなるの?
SELECT
hoge,hogehoge,hoge2
FROM
A
JOIN B
ON A.hoge = B.hoge
WHERE
hoge > 3;
この時の実行順序は以下の通り。
FROM句→ON句→JOIN句→WHERE句→SELECT句
これも考え方としては、
FROM句でベースとなるテーブルを抽出し、ON句でテーブルとテーブルを結合するキーを抽出し、JOIN句でテーブルとテーブルを結合して、WHERE句でレコードを絞り、SELECT句で列を絞る。
ON句→JOIN句でこれから使うテーブルを作るので、WHERE句が行われる前にJOIN句が実行される。
GROUP BYはどこで評価されるの?
SELECT
hoge
FROM
A
JOIN B
ON A.hoge = B.hoge
WHERE
hoge > 3
GROUP BY
hoge;
GROUP BYを入れた時の評価順序は以下の通り。
FROM句→ON句→JOIN句→WHERE句→JOIN句→SELECT句
GROUP BYはWHERE句の後で処理がされる。
WHERE句で行を絞った後にグルーピングする為です。
どうしてGROUP BYでASが使えないのか?
GROUP BYで列別名が使えないのは、この評価順序の問題だったりします。
GROUP BYはSELECT句よりも前に実行されます。
SELECT文で列別名を定義しているので、GROUP BYが実行する段階では列別名は存在しない訳です。
同じくWHERE句でも列別名が使えないのは、そういうことです。
SELECT句よりも後に評価される句ならば、列別名が使えたりします。
例えば、ORDER BYとか。。。
最後に
SQLの評価順序を意識することはとっても大事。