[SQL]別名を付けた(AS句)カラムをWHERE句で使えなかった話。(解決方法記載あり。)

#DB
writtdden by 神聖眼鏡くん

どうも神聖眼鏡です。
早いもので1月も終わってしまいますね。
一年重ねていくごとに1年はあっという間だなと2023年始まって早々に感じました。
さて、今回はSQLにでつまづいた話を記載していきます。

状況

SELECTで別名をつけたカラムに対して、WHEREで条件を絞りたいと思ったところ、以下のようにエラーが出て使えなかった。

列 'limit_date_a' (別名つけたカラム)は 'where clause' にはありません。

調べてみると、エイリアスしたものはWHERE句で使えないとのこと。

ちなみに私が行ったSQL配下です。(ある程度省略しています)

SELECT id, ..... 
 case
  when method_a = 0 OR `method_a_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_a_apply_limit_date`
 end as limit_date_a,
 case
  when method_b = 0 OR `method_b_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_b_apply_limit_date`
 end as limit_date_b,
 case
  when method_c = 0 OR `method_c_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_c_apply_limit_date`
 end as limit_date_c
 FROM tabale
 WHERE(
  ( `limit_date_a` <= '2023-01-29 15:55:01') AND
  ( `limit_date_b` <= '2023-01-29 15:55:01') AND
  ( `limit_date_c` <= '2023-01-29 15:55:01' )
 )

解決方法

WHERE句が使えない代わりにHAVINGを使いました。
HAVINGはWHEREと同じように条件を絞ってくれるので同じような感覚で使えます。
違う点としては、実行されるタイミングです。

WHERE句はグループ化をされる前に、つまり元々のデータでの抽出条件を指定できる。(加工したデータはNG)
HAVING句はグループ化した後の情報での、抽出条件を指定できる。(加工したデータOK)

修正後は以下のようにし、実行できました!

SELECT id, ..... 
 case
  when method_a = 0 OR `method_a_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_a_apply_limit_date`
 end as limit_date_a,
 case
  when method_b = 0 OR `method_b_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_b_apply_limit_date`
 end as limit_date_b,
 case
  when method_c = 0 OR `method_c_apply_limit_date` IS NULL then '0000-00-00 00:00:00'
 else `method_c_apply_limit_date`
 end as limit_date_c
 FROM tabale
 HAVING(
  ( `limit_date_a` <= '2023-01-29 15:55:01') AND
  ( `limit_date_b` <= '2023-01-29 15:55:01') AND
  ( `limit_date_c` <= '2023-01-29 15:55:01' )
 )

終わりに

シンプルなSQLではWHEREもHAVINGも違いはないですが、複雑になるほど気を付けなければならないですね。
最後まで閲覧にいただき、ありがとうございました。

関連ブログ
【MySQL】CASE文による条件分岐
【MySQL】SQLの基本構文と稀に使うサンプル ~重複削除・Indexなど~

Favorite