seminar
|seminar_id|seminar_date_1|seminar_date_2|
上記のようなテーブルがあるとして
SELECT seminar_id,
(CASE
WHEN seminar_date_2 = '0000-00-00'
THEN seminar_date_1
ELSE seminar_date_2
END) AS start_date FROM seminar
WHERE start_date > CURDATE()
が通らず、
#1054 - Unknown column 'start_date' in 'where clause'
とエラーを返します。
WHEREをHAVINGに変えると通るのですが、
HAVINGは集合に対して使うものだと思うので腑に落ちません。
私が何か思い違いをしているのでしょうか?
エイリアスで指定できるのはHAVINGとORDER BYだけです。
WHEREはとおりません。
http://dev.mysql.com/doc/refman/4.1/ja/select.html
HAVINGは構文上はGROUP BYが無くても通りますね。変ですけど。
WHERE
(CASE
WHEN seminar_date_2 = '0000-00-00'
THEN seminar_date_1
ELSE seminar_date_2
END) > CURDATE()
です。
WHERE句のほうが先に評価されるのでstart_timeが使えません。
なので泥臭いですが、以下のように書き直せると思います。
SELECT seminar_id, (CASE WHEN seminar_date_2 = '0000-00-00' THEN seminar_date_1 ELSE seminar_date_2 END) AS start_date FROM seminar WHERE (CASE WHEN seminar_date_2 = '0000-00-00' THEN seminar_date_1 ELSE seminar_date_2 END) > CURDATE()
HAVING句がこのように使えるのは少し驚きました(PostgreSQL8.3だとHAVING版は通りませんでした)。
名前の有効範囲には、RDBMSやそのバージョンにより仕様差があります。
インラインビュー化して内側のクエリで別名を付ければ、外側のクエリでその別名を検索条件で指定できます。
SELECT * FROM( SELECT seminar_id, CASE WHEN seminar_date_2 = '0000-00-00' THEN seminar_date_1 ELSE seminar_date_2 END) AS start_date FROM seminar ) AS x WHERE start_date > CURDATE()
SELECTとWHEREで同じCASE式を二重に書くのはさすがに嫌なので、
どのRDBMSでも通りそうなこれが無難そうですかね。
MySQL限定でalias問題を解決するHAVINGのhackな使い方、
という事で私の中では落ち着きました。