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
助言がありますか?
operator precedence が原因でクエリは失敗します。 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
条件がない(AND
がない)場合、括弧はneedしません。受け入れられた答えは、この点で少し誤解を招きます。
SELECT *
FROM tbl_name
WHERE coalesce(id_field,'unik_null_value')
IN ('value1', 'value2', 'value3', 'unik_null_value')
そのため、チェックからヌルを除去します。 id_fieldにnull値が与えられた場合、合体関数はnullの代わりに 'unik_null_value'を返し、IN-listに 'unik_null_valueを追加すると、クエリはid_fieldがvalue1-3またはnullの投稿を返します。
ダニエルが答えた質問は、完全に問題ありません。 NULLに関するメモを残したかった。列にNULL値が含まれる場合は、NOT IN演算子の使用に注意する必要があります。列にNULL値が含まれていて、NOT IN演算子を使用している場合、出力は得られません。これは、ここで説明されている方法です http://www.oraclebin.com/2013/01/beware-of-nulls.html 、私が出会って共有したいと思った非常に良い記事です。
注:外部リンクが死んでいると誰かが主張したのでSushant Butta's answer私は別の回答としてここにコンテンツを投稿しました。
[〜#〜] 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.
ここで、IN
演算子を使用してtable_a
から値をチェックすることにより、table_b
の値の存在をチェックするクエリを実行します。
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
出力は予想通りでした。テーブルtable_b
にnull
値を挿入し、上記の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_b
のデータにあります。テーブルにnull
値を導入しました。しかし、なぜこのように動作するのでしょうか? 2つのクエリを"AND"
および"OR"
演算子に分割しましょう。
最初のクエリは、このように内部的に処理されます。したがって、最初の2つのオペランドがnull
またはtrue
に評価されるため、false
が問題になることはありません。しかし、私の第3オペランドa = null
は、true
にもfalse
にも評価されません。 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番目のクエリは次のように処理されます。 "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_b
からすべてのNOT IN
値を選択します。
SQL> select * from table_a where a not in (select * from table_b where b is not null);
A
----------
1
2
したがって、NOT IN
演算子を使用するときは、列のNULL
値に常に注意してください。
NULL !!に注意してください
私はそれが答えるのが遅いことを知っていますが、他の誰かにとっては有用かもしれませんあなたはサブクエリを使用して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)