• ベストアンサー

【初歩】 SELECT文で意図した照会結果が得られない。NULLの扱いは?

var1 var2 ------------- abc  null ------------- abc  null ------------- abc  null ------------- のようになっているテーブルに対して、 (1) select * from mytable where var1 = 'abc' (2) select * from mytable where var1 = 'abc' and var2 is null などとやれば、3件全部照会できますが、 (3) select * from mytable where var1 = 'abc' and var2 != '1' (4) select * from mytable where var1 = 'abc' and var2 != 1 とやっても1件も出てこないのですが、なぜでしょうか? 「NULLだって1ではない」わけだから、3件照会できてくれないと 困るのですが・・・

質問者が選んだベストアンサー

  • ベストアンサー
  • auty
  • ベストアンサー率58% (284/486)
回答No.2

やや別の見方をすると、    where 条件式 の条件式は、論理値という結果を返します。 条件式の中では、算術の演算や比較がおこなわれて、 論理値(1,2)が返されます。true,falseも使われます。 結果が論理値という点では、条件式と似ていますが、 論理演算式というのがあります。これに使われるのが、    and,or,not です。条件式との違いは、引数(計算のときに使われる値)が すべて論理値ということです。 これに対して、null値は上に出てくる値とは違った特別な値で、 ・ 多くの場合、条件式で使うと結果は、null値を返す。 ・ or以外の論理演算式で使っても、結果は、null値を返す。 例として、下記は、すべてnullを返します。 ----------------------------------------------------------- select 100 * null, "abc" + null; select 0 = null, 0 != null; select 1 = null, 1 != null; select not null; select true and null;  (3)',(4)' ----------------------------------------------------------- 次は、1(true)を返します。 ----------------------------------------------------------- select true or null; ----------------------------------------------------------- そこで、null値をチェックするため(論理値を返す) is null is not null が導入されています。論理値を返すためand等の演算子が普通に使えるわけです。 したがって、    質問の(2)は  true and true の論理演算、    質問の(3)(4)は  上の(3)',(4)'の計算を行っているわけです。 そして 条件式がnull値を返す[select ... where ...」文はレコードを全く返しません。 null値を扱うときは、他のデータベースのときと同様、十分慎重になる必要があります。 ----------------------------------------------------------- ちなみに、mysqlでは現在null値をも含めて取り扱う特別な演算子も導入されています。       <=> ----------------------------------------------------------- select null <=> null;      1 select 1 <=> null;       0 select 1 <=> 1;        1 select 7 <=> 7;        1 select 7 <=> 3;        0 select "7" <=> "7";       1 -----------------------------------------------------------

litton101
質問者

お礼

autyさん、詳しく解説していただきありがとうございます。 >null値を扱うときは、他のデータベースのときと同様、十分慎重になる必要があります。 いやはや、大変勉強になりました。 is null is not null というのが特別な存在に対する特別な対処法くらいに 考えておいたほうが良さそうですね。 以後気をつけたいと思います。ありがとうございました。

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.3

coalesceとかでNULLを無視することは可能ですね (0をあえてチェックする必要がない場合にかぎりますが) select * from mytable where var1 = 'abc' and COALESCE(var2,0) != 1

litton101
質問者

お礼

yamabejpさん、対処法をご教示いただきありがとうございました。 教わった方法でいこうかとも思いましたがNULLを作らず0をINSERTするようにPHPの方のコードを書き換えることとしました。ありがとうございました。

回答No.1

SQLの基本ですが、 nullの判定は、 「列名 is null」 または 「列名 is not null」 でないと行えません。 nullは「不定」な値であり、「1かどうか判定できない」という値です。 また、Oracleなど一部のRDBMSでは、 「列名=null」 といった条件でnullの判定ができるようですが、これは少数派です。文法的には間違いではなく、エラーにならないので注意してください。

litton101
質問者

お礼

chukenkenkouさん、ご回答ありがとうございました。 >「1かどうか判定できない」という値です そういうことでしたか。 こちらの理解が浅かったようです。 おかげさまで勉強になりました。