NULLまたはISNULLのIN句


83

Postgresはデータベースです

IN句にNULL値を使用できますか?例:

SELECT *
FROM tbl_name
WHERE id_field IN ('value1', 'value2', 'value3', NULL)

これらの4つの値に制限したいと思います。

上記のステートメントを試しましたが、機能しません。実行されますが、ID_fieldsがNULLのレコードは追加されません。

OR条件も追加しようとしましたが、これによりクエリが実行され、終わりが見えなくなります。

SELECT *
FROM tbl_name
WHERE other_condition = bar
AND another_condition = foo
AND id_field IN ('value1', 'value2', 'value3')
OR id_field IS NULL

助言がありますか?


10
in文は同じように解析されますfield=val1 or field=val2 or field=val3。そこにnullを入れると、結局field=nullは機能しません。
マークB

1
2番目のクエリは正しいはずです。あなたのwhere条項には他にどのようなものがありますか?
ダニエルA.ホワイト

@Daniel A. White、より多くの条件でクエリを反映するように更新
Phill Pafford 2011年

回答:


122

in文は同じように解析されますfield=val1 or field=val2 or field=val3。そこにnullを入れると、結局field=nullは機能しません。

マークBによるコメント

私は賢さのためにこれをします

SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)

ああ、それをやった、ありがとう!したがって、フィールドをラップすると、両方の条件がWHERE句に追加されますか?明確にするために
Phill Pafford 2011年

1
@ Phill-それは操作の順序の問題でした。
ダニエルA.ホワイト

20

演算子の優先順位が原因でクエリが失敗します。AND前にバインドしORます!
「明確さ」の問題ではなく、純粋な論理の必要性である括弧のペアが必要です。

SELECT *
FROM   tbl_name
WHERE  other_condition = bar
AND    another_condition = foo
AND   (id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)

追加された括弧は、のAND前のバインドを防ぎORます。他のWHERE条件がない場合(no AND)、括弧は必要ありません。受け入れられた答えは、この点で少し誤解を招くものです。


15
SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value') 
IN ('value1', 'value2', 'value3', 'unik_null_value')

そのため、チェックからnullを削除します。id_fieldにnull値が与えられた場合、合体関数はnullの代わりに 'unik_null_value'を返し、 'unik_null_valueをINリストに追加することにより、クエリはid_fieldがvalue1-3またはnullである投稿を返します。


2
少しの説明が将来の読者に役立つでしょう。コードは問題の解決にどのように役立ちますか?
showdev 2016

9

ダニエルが答えた質問は完全に問題ありません。NULLSについてメモを残したかった。列にNULL値が含まれている場合は、NOTIN演算子の使用に注意する必要があります。列にNULL値が含まれていて、NOT IN演算子を使用している場合、出力は得られません。これは、ここhttp://www.oraclebin.com/2013/01/beware-of-nulls.htmlで説明されている方法です。これは、私が出くわして共有しようと考えた非常に優れた記事です。


この問題が発生した使用回数はわかりませんが、nullとNOT IN演算子の混合でこの問題が発生し、過去2時間にわたって問題が発生していました。これは... PERPある
Govindライ

1
リンクが切れています。
ダグHøidahl

1
そんなものが今生きています。
常に学習者2017

3

注:Sushant Buttaの回答で外部リンクが無効であると誰かが主張したため、別の回答としてここにコンテンツを投稿しました。

NULLSに注意してください。

今日、INとNOT IN演算子を使用しているときに、クエリの非常に奇妙な動作に遭遇しました。実際、2つのテーブルを比較table bして、からの値がに存在するかどうかtable aを調べ、列にnull値が含まれている場合の動作を調べたいと思いました。そこで、この動作をテストするための環境を作成しました。

テーブルを作成しますtable_a

SQL> create table table_a ( a number);
Table created.

テーブルを作成しますtable_b

SQL> create table table_b ( b number);
Table created.

にいくつかの値を挿入しtable_aます。

SQL> insert into table_a values (1);
1 row created.

SQL> insert into table_a values (2);
1 row created.

SQL> insert into table_a values (3);
1 row created.

にいくつかの値を挿入しtable_bます。

SQL> insert into table_b values(4);
1 row created.

SQL> insert into table_b values(3);
1 row created.

次に、クエリを実行して、演算子table_atable_b使用して値をチェックすることにより、の値の存在をチェックしますIN

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

以下のクエリを実行して、存在しないことを確認します。

SQL> select * from table_a where a not in (select * from table_b);
         A
----------
         1
         2

出力は期待どおりになりました。次にnull、テーブルに値を挿入しtable_b、上記の2つのクエリがどのように動作するかを確認します。

SQL> insert into table_b values(null);
1 row created.

SQL> select * from table_a where a in (select * from table_b);
         A
----------
         3

SQL> select * from table_a where a not in (select * from table_b);

no rows selected

最初のクエリは期待どおりに動作しましたが、2番目のクエリはどうなりましたか?なぜ出力が得られなかったのですか、何が起こったのでしょうか?クエリに違いはありますか?いいえ

変更はテーブルのデータにありますtable_bnull表に値を導入しました。しかし、なぜそれがこのように動作しているのですか?2つのクエリを"AND""OR"演算子に分割してみましょう。

最初のクエリ:

最初のクエリは、このような内部で処理されます。だから、null私の最初の2つのオペランドがどちらかに評価するとして、ここで問題を作成しませんtruefalse。しかし、私の3番目のオペランドa = nullは評価truefalse。もしません。nullのみに評価されます。

select * from table_a whara a = 3 or a = 4 or a = null;

a = 3  is either true or false
a = 4  is either true or false
a = null is null

2番目のクエリ:

2番目のクエリは次のように処理されます。"AND"演算子を使用しているためtrue、どのオペランド以外でも出力は得られません。

select * from table_a whara a <> 3 and a <> 4 and a <> null;

a <> 3 is either true or false
a <> 4 is either true or false
a <> null is null

では、これをどのように処理するのでしょうか。演算子を使用しながらnot null、テーブルからすべての値を選択します。table_bNOT IN

SQL> select * from table_a where a not in (select * from table_b where b is not null);

         A
----------
         1
         2

したがってNULLNOT IN演算子を使用するときは、列の値に常に注意してください。

NULLに注意してください!!


素晴らしい答え。私は自分の仕事で問題を発見したばかりです。Oracleの非常に奇妙な動作。
oputyk

0

私はそれが答えるのが遅いことを知っていますが、他の誰かのために役立つかもしれませんあなたはサブクエリを使ってnullを0に変換することができます

SELECT *
FROM (SELECT CASE WHEN id_field IS NULL 
                THEN 0 
                ELSE id_field 
            END AS id_field
      FROM tbl_name) AS tbl
WHERE tbl.id_field IN ('value1', 'value2', 'value3', 0)

これは、合体を使用したOveHalsethの回答に似ています。
user890332

0

Nullデータがないことを指します。Null正式には、使用できない、割り当てられていない、不明である、または適用できない値として定義されています(OCA Oracle Database 12c、SQL Fundamentals I Exam Guide、p87)。そのため、「in」または「not in」句を使用して列が制限されている場合、null値を含む列を含むレコードが表示されない場合があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.