SQL ServerのT-SQLではSELECT文の取得するカラム名の別名(エイリアス)がORDER BYでは使えるが、WHEREやGROUP BYでは使えません。
実はこれが長年の疑問でした。
今日はそれが解決しました。
SELECT文で別名(エイリアス)が使える、使えないはSQL実行順序で決まる
ということです。
使えると結構SQLが短くかけたりします。
例えば
SELECT personal_no AS no ,personal_name AS name ,CASE WHEN personal_gender = 0 THEN '男性' else '女性' END AS gender FROM test_table WHERE personal_no < 100 GROUP BY personal_no ,personal_name ,CASE WHEN personal_gender = 0 THEN '男性' else '女性' END ORDER BY personal_no ,gender
の「GROUP BY」にある「CASE WHEN personal_gender = 0 THEN ‘男性’ else ‘女性’ END」がSELECT句で指定している「gender」に置き換えられれば良いのですが、置き換えるとエラーになります。
メッセージ 207、レベル 16、状態 1、行 14 列名 'gender' が無効です。
でも「ORDER BY」句に「gender」を指定してもエラーになりません。
何故なんでしょう?
SQLを処理する順番で別名(エイリアス)が使えるかどうか決まる
実はこれ、SQLを処理する順番で別名(エイリアス)が使えるかどうか決まるのです。
SELECT ステートメントの論理的な処理順序
SQL ServerでのSELECT ステートメントの論理的な処理順序はSELECT (Transact-SQL)にある通り
- FROM
- ON
- JOIN
- WHERE
- GROUP BY
- WITH CUBE または WITH ROLLUP
- HAVING
- SELECT
- DISTINCT
- ORDER BY
- TOP
です。
なのでSELECT句で指定したカラムの別名(エイリアス:ASで指定した名前)はORDER BYでは使えるが、WHEREやGROUP BYではまだ処理されてないので使えないのですね。
やっと理由がわかりました。
まとめ
SELECT文で別名(エイリアス)が使える、使えないはSQL実行順序で決まります。
OracleやPostgreSQL、MySQLなどでも調べてみると違いがあるのかもしれません。
以上、SELECTで別名・エイリアスが使えるかはSQL実行順序で決まるでした。