Knowledge‎ > ‎

Olacle - NOT条件


テーブルにレコードが3件入っています。
-- (1)
select * from TABLE_A where COlUMN_1 < '2011-06-09'
でレコードが1件ヒットしました。
では以下の条件では何件ヒットするでしょうか?
-- (2)
select * from TABLE_A where NOT (COlUMN_1 < '2011-06-09')

私は、NOTは概念的に完全な論理演算をしてくれると思い込んでいたので、この答えは2件になると思っていました。つまり、NOTをつけない条件の結果とNOTをつけた条件の合計は全量になると。しかし確認のために実際に実行してみると、この考えは間違っていることが分かりました。


実際には(2)は下記のSQLと等価になります。
-- (3)
select * from TABLE_A where COlUMN_1 >= '2011-06-09'

OracleではカラムがNULLのレコードは、等号・不等号の比較では無視されます。
つまり(3)の実行結果は、カラムの内容により0,1,2のいずれかの値をとりうるということになります。

一方で以下の式。
-- (4)
select * from TABLE_A where COlUMN_1 < '2011-06-09' AND COlUMN_1 IS NOT NULL
(4)の結果は(1)と同じ結果になります。
で、この条件部分全体を否定した以下のSQLはどうでしょうか?

-- (5)
select * from TABLE_A where NOT (COlUMN_1 < '2011-06-09' AND COlUMN_1 IS NOT NULL)
この結果は2件になり、(4)と(5)を合計したものは全量ということになります。


ちょっとした違いですが、気をつけないといけませんね。

※実はDELETE文で削除条件に使っていた条件式を、truncate&insertで書き直すためにNOTで反転して使用と思っていたのですが、NULLの場合に元の仕様と異なる動きをしてしまうバグを埋め込むところでした。思い込みで突き進むのではなく、念のため検証してみてよかったです。