postgresql 带NULL或IS NULL的IN子句

46scxncf  于 2023-05-06  发布在  PostgreSQL
关注(0)|答案(8)|浏览(381)

Postgres是数据库
我可以为IN子句使用NULL值吗?例如:

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

我想把这四个值限制在这里。
我已经尝试了上面的语句,它不起作用,它执行,但不添加记录与NULL id_fields。
我还尝试添加一个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

有什么建议吗?

vkc1a9a2

vkc1a9a21#

in语句的解析方式与field=val1 or field=val2 or field=val3相同。在这里输入null将归结为field=null,这将不起作用。
(来源:Marc B
我会为了clairity这么做的

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

bqf10yzr2#

由于运算符优先级,您的查询失败。ANDOR之前绑定!
你需要一对括号,这不是“清晰”的问题,而是纯粹的 * 逻辑必要性 *。

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),则不需要额外的括号。在这方面,公认的答案具有误导性。

8gsdolmq

8gsdolmq3#

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

这样就可以从检查中消除null。给定id_field中的null值,coalce函数将返回'unik_null_value'而不是null,并且通过将'unik_null_value添加到IN列表中,查询将返回id_field为value 1 -3或null的post。

xtupzzrd

xtupzzrd4#

丹尼尔回答的问题完全正确。我想留下一张关于空的便条。当一个列包含NULL值时,我们应该小心使用NOT IN操作符。如果您的列包含NULL值并且您正在使用NOT IN运算符,则不会得到任何输出。这就是它是如何解释在这里http://www.oraclebin.com/2013/01/beware-of-nulls.html,一个非常好的文章,我遇到并认为分享它。

r6vfmomb

r6vfmomb5#

    • 注意:由于有人声称外部链接在Sushant Butta的**回答中已经死亡,我将内容作为单独的答案发布在这里。

小心空值
今天我在使用IN和NOT IN操作符时遇到了一个非常奇怪的查询行为。实际上,我想比较两个表,找出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_b中检查值来检查table_a中是否存在值。

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值,并查看上述两个查询的行为。

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

第一个查询的行为符合预期,但第二个查询发生了什么?为什么我们没有得到任何输出,应该发生什么?查询是否有任何差异?* * 没有**。
table_b的数据发生了变化。我们在表中引入了null值。但它为什么会这样?让我们将这两个查询拆分为"AND""OR"运算符。

第一个查询:

第一个查询将在内部处理,类似于下面的代码。因此,null在这里不会产生问题,因为我的前两个操作数将计算为truefalse。但是我的第三个操作数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

第二次查询:

第二个查询将按如下方式处理。由于我们使用的是"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 IN运算符时从表table_b中选取所有not null值。

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!!**
tquggr8v

tquggr8v6#

我知道这是晚回答,但可能是有用的其他人你可以使用子查询和转换为空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)
j8yoct9x

j8yoct9x7#

Null表示数据缺失。Null被正式定义为不可用、未分配、未知或不适用的值(OCA Oracle Database 12c,SQL Fundamentals I Exam Guide,p87)。因此,当使用“in”或“not in”子句限制列时,您可能看不到包含空值的列的记录。

dkqlctbz

dkqlctbz8#

EASY:这将给予TRUE和null值:

SELECT *
FROM tbl_name
WHERE 
id_field IN ('value1', 'value2', 'value3') IS NOT FALSE;

相关问题