where句で以下の比較の結果にはまりました。。
mysql> select -> '1' = '0' -> ,'1' = 0 -> ,'A' = '0' -> ,'A' = 0 -- これは真 -> ,'1' = '1' -> ,'1' = 1 -> ,'1A' = '1' -> ,'1A' = 1 -- ついでにこれも真 -> ; +-----------+---------+-----------+---------+-----------+---------+------------+----------+ | '1' = '0' | '1' = 0 | 'A' = '0' | 'A' = 0 | '1' = '1' | '1' = 1 | '1A' = '1' | '1A' = 1 | +-----------+---------+-----------+---------+-----------+---------+------------+----------+ | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | +-----------+---------+-----------+---------+-----------+---------+------------+----------+ 1 row in set (0.00 sec)
理由は、以下の仕様で暗黙の型変換が起きているから。
mysql> select -> cast('1' as signed) -> ,cast('A' as signed) -> ,cast('1A' as signed) -> ,cast('1A2' as signed) -> ; +---------------------+---------------------+----------------------+-----------------------+ | cast('1' as signed) | cast('A' as signed) | cast('1A' as signed) | cast('1A2' as signed) | +---------------------+---------------------+----------------------+-----------------------+ | 1 | 0 | 1 | 1 | +---------------------+---------------------+----------------------+-----------------------+ 1 row in set, 3 warnings (0.00 sec)
1.charとintの比較はintに寄せる型変換が起こる。
2.charを前から一文字ずつintに変換していって、変換不能な場合は0と評価し、変換を終了する。
3.なので、'A' は 0 に変換され、結果'A' = 0 なんかは 0 = 0 になっちゃって「真」。
暗黙の型変換はSQL自体には仕様がないので、実装依存だそう。これはmysql4.1でやってます。Oracleでは、エラーにしてくれるとか。そっちのほうが潔い気が。