带有 NULL 或 IS NULL 的 IN 子句

问题描述 投票:0回答:9

我可以在 IN 子句中使用 NULL 值吗?示例:

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

我想限制为这四个值。

我已经尝试过上面的说法,但不起作用。好吧,它执行了,但没有添加 id_field 为 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

有什么建议吗?

sql postgresql null conditional-statements in-clause
9个回答
189
投票

in
语句的解析方式与
field=val1 or field=val2 or field=val3
相同。在那里输入 null 会归结为
field=null
,这是行不通的。

评论Marc B

为了清楚起见,我会这样做

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

33
投票

由于 运算符优先级,您的查询失败。

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


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

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


16
投票

丹尼尔回答的问题完全没问题。我想留下关于 NULLS 的注释。当列包含 NULL 值时,我们应该小心使用 NOT IN 运算符。如果您的列包含 NULL 值并且您使用 NOT IN 运算符,您将不会获得任何输出。这就是这里的解释方式http://www.oraclebin.com/2013/01/beware-of-nulls.html,这是一篇非常好的文章,我偶然发现并想分享它。


13
投票

注意:由于有人声称外部链接在Sushant Butta的答案中已失效,所以我已将内容作为单独的答案发布在这里。

谨防 NULLS

今天,我在使用 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.

现在我们将执行一个查询,通过使用

table_a
运算符检查
table_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
值,并查看上述两个查询的行为。

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
不会在这里产生问题,因为我的前两个操作数将计算为
true
false
。但我的第三个操作数
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 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

因此,在使用

NULL
运算符时,请务必小心列中的
NOT IN
值。

谨防NULL!!


2
投票

简单:这将给出 TRUE 和 null 值:

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

1
投票

我知道回答已经晚了,但对其他人可能有用 您可以使用子查询并将 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)

0
投票

Null
表示缺少数据。
Null
正式定义为不可用、未分配、未知或不适用的值(OCA Oracle Database 12c、SQL 基础知识 I 考试指南,第 87 页)。 因此,当使用“in”或“not in”子句限制所述列时,您可能看不到包含空值的列的记录。


0
投票

如果您的字段是数字类型,这是我成功使用的解决方案。

(campaignid::($campaignid) 中的文本或(campaignid 为 null 且 ($campaignid) 中为“null”))

© www.soinside.com 2019 - 2024. All rights reserved.