MySQLにおいて


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は集合に対して使うものだと思うので腑に落ちません。

私が何か思い違いをしているのでしょうか?

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2009/10/09 23:30:02
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答3件)

id:angemaries No.1

回答回数80ベストアンサー獲得回数2

ポイント27pt

エイリアスで指定できるのは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()

です。

id:FnuLnu

MySQL限定でalias問題を解決するHAVINGのhackな使い方、

という事で私の中では落ち着きました。

2009/10/05 05:24:38
id:komamitsu No.2

回答回数21ベストアンサー獲得回数2

ポイント27pt

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版は通りませんでした)。

id:FnuLnu

http://dev.mysql.com/doc/refman/4.1/ja/problems-with-alias.html

ああ、なるほど。

単純にエイリアスの評価順の問題なんですね。

2009/10/05 05:16:08
id:chuken_kenkou No.3

回答回数722ベストアンサー獲得回数54

ポイント26pt

名前の有効範囲には、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()
id:FnuLnu

SELECTとWHEREで同じCASE式を二重に書くのはさすがに嫌なので、

どのRDBMSでも通りそうなこれが無難そうですかね。

2009/10/05 05:21:41
  • id:chuken_kenkou
    提示したSELECT文で、右括弧が一個多かったので訂正。

    CASE ・・・ END の直後の「)」が余分でした。

    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 「)」が余分だった
    -- ↓訂正部分
    END AS start_date
    FROM seminar
    ) AS x
    WHERE start_date > CURDATE()


    なお、FROM句でSELECT文を書くいわゆる「インラインビュー」ですが、MySQLでは4.1で実装だったと思います。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません