MySQL5で「Unknown column … in ‘on clause’」エラーが出る場合の対処法

MySQL5系に移したら突然動かなくなった…

MySQL3とかMySQL4でこれまで運用してきたシステムがMySQL5系になって急に動かなくなった経験はありませんか?

実際にSQL文を双方に入力しても、旧バージョンだとちゃんと動きますが、MySQL5系では以下のようなエラーが出ることがあります。 そして大抵、そのSQL文には以下の条件が含まれているはずです。

エラー内容

Unknown column ... in 'on clause'

エラーが出るSQL文条件

  • 「FROM a,b」 のように複数のテーブルを参照している。
  • 「JOIN」構文が含まれている。

原因はJOIN構文の優先度変更

答えはMySQLのマニュアルに書いてあるのですが、JOINの優先度が高くなったしまったために、カンマよりも勝ってしまうことによる構文エラーだったのですね。

MySQL 5.1 リファレンスマニュアル :: 12.2.7.1 JOIN 構文

以前は、カンマ演算子(,)と JOIN の両方は同じ優先順位だったので、接合式 t1, t2 JOIN t3 は ((t1, t2) JOIN t3) として解釈されました。現在は JOIN が高い優先順位を持つので、式は (t1, (t2 JOIN t3)) として解釈されます。この変更は、ON 条項が接合の演算子内のカラムだけを参照する事ができ、優先順位の変更はそれらの演算子が何であるかについての解釈を変えてしまうので、この条項を利用するステートメントに影響を与えます。

たとえば、t1,t2,t3とテーブルがあったとして、以下のSQL文を発行します。

SELECT * FROM t1, t2 JOIN t3 ON (t1.i1 = t3.i3);

以前は、(t1,t2) としての t1,t2 の暗黙のグループ分けのおかげで、SELECT は正当でした。現在は JOIN が優先順位を持つので ON 条項の演算子は t2 と t3 です。t1.i1 がどちらの演算子でもないので、結果は Unknown column ‘t1.i1’ in ‘on clause’ エラーになります。接合を実行させるには、ON 条項の演算子が (t1,t2) と t3 となるように、括弧を利用して最初の2つのテーブルを明示的にグループ分けして下さい。

SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);

または、カンマ演算を利用するのを避け、その代わりに JOIN を利用してください。

SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);

結論は

FROMで参照する複数テーブルを括弧で囲め!

ということなのでした。 しかし、SQL文を書き換えないといけないことになるので、ちょっと厄介ですよね。。 とはいえ、今のところこれしかないと思いますので、地道に修正していきましょう。

このページをシェアする

2009-09-04