明るく

暗く

SQL

【Oracle SQL】ノットイコール(<>/!=)でNULLも含めて抽出する方法│IS NULL併用の書き方

【Oracle SQL】ノットイコール(<>/!=)でNULLも含めて抽出する方法│IS NULL併用の書き方

SQLで「B以外」を抽出するために WHERE column <> 'B'WHERE column != 'B' と書いたのに、NULLのデータが取得できず困っていませんか?

 

ノットイコール(<>!=)だけではNULLは抽出されません。NULLも含めて取得したい場合は、WHERE column <> 'B' OR column IS NULLのように IS NULLを併用します。

 

この記事では、ノットイコール(<>!=)でNULLが取得できない理由と、NULLも含めて抽出するためのWHERE条件の書き方を解説します。また、NOT INを使う場合の注意点についても紹介します。

環境

今回はOracle Databaseサーバー、PL/SQLで説明ます。

課題:ノットイコール(<>/!=)でNULLも取得するには?

先に結論です。ノットイコール(NOTイコール、<> / !=)だけだと、NULLは不明(UNKNOWN)扱いになり、条件に一致しません。NULLも含めたい場合は、WHERE (column <> 'B' OR column IS NULL) のように、IS NULLを併用します。

 

これを確認するために、SQLで特定の文字以外の条件でデータを取得する際に起こる現象を取り上げます。下記のようなテーブル(テーブル名:table_1)があり、「column」という名前のカラムからB以外の特定の文字を取得するとしましょう。

 

column
A
B
NULL
C

 

まずノットイコール(<>,!=)を使って、B以外という条件を指定します。

 

SELECT column FROM table_1 WHERE column <> 'B' ;

 

または、

 

SELECT column FROM table_1 WHERE column != 'B' ;

となります。この場合、下記のようにA・Cが表示されNULLが取得されません

 

column
A
C

 

ではA・Cに加えてNULLも取得したい場合は、どのように条件を書けばよいのでしょうか?

ノットイコール(<>/!=)でNULLが取得できない理由

ノットイコール(<>,!=)で条件を指定すると、特定の値以外は取得できます。しかしNULLは通常の値とは扱いが異なるため、期待した結果にならないことがあります。

 

ここでは、ノットイコールでNULLが取得できない理由と、NULLも含めて抽出するための考え方を見ていきます。

ノットイコール(<>/!=)は「等しくない値」を抽出する条件

そもそもノットイコールとは、「等しくない」「以外」という意味です。例えば以下の図のように、A・B・Cという文字があります。X ノットイコール Bは、X が A か C であることを指し、以下の図ではグレーの部分に該当しますノットイコール(<>、!=)解説図:英語

これは文字(String型)だけでなく、数字の場合でも同様です例えば以下の図のように、1・2・3という文字があります。X ノットイコール 1 は、X が 2 か 3 であることを指し、以下の図ではグレーの部分に該当します。

ノットイコール(<>、!=)解説図:数字

NULLは値ではないため、<> / != ではTRUEにならない

SQLでは、NULLは「値が入っていない状態」を表します。そのため、通常の比較演算子だけでは、’B’ と等しいか等しくないかを判定できません。

 

column <> 'B' と書いた場合、NULLの行はTRUEではなくUNKNOWNとして扱われるため、WHERE句の条件に一致しません。

NOT INでもNULL行は抽出されない

NOT INも指定した値以外を抽出できますが、NULLが入っている行はNOT INだけでは拾えません。NULLも含めるには、IS NULLを併用します。

 

複数条件に合致するかどうかをまとめて判別するINに対して、指定した複数の条件のどれにも該当しないものを抽出するのがNOT INです。

 

例えば以下の図のように、A・B・Cという文字があります。X NOT IN (A,B)は、X が C であることを指し、以下の図ではグレーの部分に該当します。NOT IN解説図

スクリプトは以下のように書きます。

 

SELECT column FROM table_1 WHERE column NOT IN ('A','B');

【補足】PL/SQL限定のノットイコール演算子(^=、~=)は使わない

^=~= は、OracleのPL/SQLで使える「等しくない(ノットイコール)」の書き方です。ただし、SQL Serverなど別のデータベースでは使えず、将来ほかの環境で動かしたいとき(例:Oracle DatabaseからSQL Serverに移行する)に、エラーの原因になります。

 

そのため、普段は標準的な <>(または !=)を使うのがおすすめです。

 

一方で、古いPL/SQLのコードでは ^=~= が出てくることもあります。見かけたときに困らないように、PL/SQLだけの ^=~= というノットイコールがあることを覚えておくと良いでしょう。

対処法:NULLを含める場合と除外する場合でWHERE条件を書き分ける

ノットイコール(<>,!=)またNOT INではNULLを抽出できません

 

NULLは文字や数字、スペース(半角/全角)とは根本的に概念が異なり、何も無い(値が存在しない)という特殊な状態を指します。そのため、ノットイコールやNOT INの条件では、NULL(を含む行)を正しく抽出できないのです。

 

※Oracleでは、文字列の空文字('')をNULLとして扱います。そのため、他のデータベースでいう「空文字(空の文字列)」を、Oracleでは別の値として扱えないことがあります。

B以外にNULLも含める場合は OR column IS NULL を追加する

今回の課題は、A、B、C、NULLのうち、B以外のすべてのデータを取得することです。しかし前述の通り、ノットイコールだけではNULLのレコードを取得できません。そのため、B以外のデータでNULLも含める場合は、条件式に IS NULL を付ける必要があります。

 

SELECT column FROM table_1 WHERE column <> 'B' OR column IS NULL;

 

これで、NULLを含めたB以外のデータを取得できます。

 

column
A
C
NULL

A・B以外にNULLも含める場合は NOT IN と IS NULL を併用する

例えばA・B以外のデータを取得したい場合は、複数の条件に該当しない要素を抽出するNOT INを使います。しかしNOT INもノットイコールと同様、そのままではNULLのデータを取得できません。

 

そのため、結果にNULLも含めたい場合は、別途 IS NULL を付ける必要があります

 

SELECT column FROM table_1 WHERE column NOT IN ('A','B') OR column IS NULL;

 

これでNULLを含め、A・B以外のデータを取得できます。

 

column
C
NULL

NULL以外だけを抽出する場合は IS NOT NULL を使う

NULL以外を探したい場合は、IS NOT NULL演算子を使います。
 
SELECT column FROM table_1 WHERE column IS NOT NULL;

 

これでNULL以外のデータを取得できます。
 
column
A
B
C

 

コラム:SQL ServerでもNULLを取得するには IS NULL が必要

 

企業でよく使われているサーバーに、SQL Serverがあります。こちらもノットイコールの演算子は(<>!=)です。

 

SQL Serverも同様に、ノットイコールではNULLを抽出できません。IS NULLが必要です

 

select column from table_1 WHERE column <> 'B' OR column IS NULL;

 

上記のスクリプトで特定の文字以外の文字とNULLが取得できます。

 

column
A
C
NULL

やりたいこと別のWHERE条件まとめ

目的別にWHERE条件を整理すると、以下のようになります。

 

やりたいこと WHERE条件
B以外を抽出する WHERE column <> 'B'
B以外にNULLも含める WHERE column <> 'B' OR column IS NULL
NULLだけを抽出する WHERE column IS NULL
NULL以外だけを抽出する WHERE column IS NOT NULL

まとめ:ノットイコール(<> / !=)でNULLも含めて抽出するなら、条件式に IS NULL を加える

ノットイコール(<>!=)や NOT IN だけでは、NULLのデータを抽出できません。NULLのデータも抽出したい場合は、条件式に IS NULL を追加しましょう。

 

特定の値以外とNULLをまとめて取得したい場合は、比較条件とIS NULLを組み合わせて条件を記述しましょう。