明るく

暗く

SQL

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

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

SQLで「B以外」を <>(または !=)で指定すると、NULLは比較結果がUNKNOWNになり条件に一致せず除外されます。NULLも含めて取得したい場合は、WHERE column <> ‘B’ OR column IS NULL のように IS NULL を併用してください。

この記事ではOracle Database(PL/SQL)前提で、NOT IN を使う場合の注意点とあわせて、最小限の例で解説します。

環境

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

今回の課題

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

 

これを確認するために、今回はSQLで特定の文字以外の条件でデータを取得する際に起こる、以下の現象を取り上げます。

 

column
A
B
NULL
C

 

上記のようなテーブル(テーブル名:table_1)あり、「column」という名前のカラムからB以外の特定の文字を取得するとしましょう。

 

まずノットイコール(<>,!=)を使って、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も取得したい場合は、どうしたらいいでしょうか。

注意!ノットイコールでは対処できない

まず原因を確認する前に、注意事項があります。PL/SQLのノットイコールの演算子には、<>!=だけではなく、^=~=というPL/SQLだけで使える演算子もあります

【スクリプトで使うのは非推奨】PL/SQLにだけあるノットイコールの演算子(^=、~=)

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

 

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

 

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

そもそもノットイコール(<>、!=)とは?

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

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

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

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');

課題への対処法

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

 

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

 

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

 

今回の課題は、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以外のデータを取得したい場合は、複数の条件に該当しない要素を抽出する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

コラム:IS NOT NULL演算子

NULL以外を探したい場合は、IS NOT NULL演算子を使います。

 

SELECT column FROM table_1 WHERE column IS NOT NULL;

 

これでNULL以外のデータを取得できました。

 

column
A
B
C

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

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

コラム:SQL Server

 

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

 

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

 

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

 

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

 

column
A
C
NULL