web-dev-qa-db-ja.com

WHERE句で列のエイリアスを使用しても機能しない

2つのフィールドusersおよびidを持つテーブルemailが与えられます。

select id, email as electronic_mail 
from (  
        select id, email 
        from users
) t 
where electronic_mail = ''

Postgresは次のように不満を述べています。

ERROR:  column "electronic_mail" does not exist

この例は、発生する問題を示すためのものです。実際のケースはより複雑です。json列の要素の配列を繰り返し、それぞれから単一のスカラー値を取得します。 (それが役立つ場合、私はいくつかのコードを共有できます。)

何が問題になるのか本当にわかりません。おそらく何か気づいていません。エイリアスされた列をWHERE句で問題なく使用できるという印象を受けましたか?

9
Victor

マニュアルはここを明確にします:

出力列の名前を使用して、ORDER BYおよびGROUP BY句の列の値を参照できますが、WHEREまたはHAVING句では使用できません。そこで、代わりに式を書き出す必要があります。

これはSQL標準によるものであり、あまり直感的でない場合があります。これの背後にある(歴史的な)理由は、SELECTクエリの一連のイベントです。 WHEREおよびHAVINGは解決されますbefore列のエイリアスが考慮されますが、GROUP BYおよびORDER BY後で発生、列のエイリアスが適用された。
また、入力名と出力名の競合は、ORDER BYGROUP BYで異なる方法で解決されることにも注意してください-もう1つの歴史的な奇妙さ(理由はありますが、それでも混乱する可能性があります)。見る:

入力列名とアプリオリに競合する列エイリアスを回避するのが最善です。

脇に:WHERE句は外部クエリの一部であるため、例のサブクエリは単なるノイズです。したがって、例は次のように簡略化できます。

select id, email as electronic_mail 
from users t 
where electronic_mail = '';  -- doesn't work
13