SELECTで別名・エイリアスが使えるかはSQL実行順序で決まる

記事内に広告が含まれています。

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)にある通り

  1. FROM
  2. ON
  3. JOIN
  4. WHERE
  5. GROUP BY
  6. WITH CUBE または WITH ROLLUP
  7. HAVING
  8. SELECT
  9. DISTINCT
  10. ORDER BY
  11. TOP

です。

なのでSELECT句で指定したカラムの別名(エイリアス:ASで指定した名前)はORDER BYでは使えるが、WHEREやGROUP BYではまだ処理されてないので使えないのですね。

やっと理由がわかりました。

まとめ

SELECT文で別名(エイリアス)が使える、使えないはSQL実行順序で決まります。

OracleやPostgreSQL、MySQLなどでも調べてみると違いがあるのかもしれません。

以上、SELECTで別名・エイリアスが使えるかはSQL実行順序で決まるでした。

タイトルとURLをコピーしました