具有NULL或IS NULL的IN子句


83

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

有什么建议么?


10
一条in语句将与解析相同field=val1 or field=val2 or field=val3。在其中放置一个null将归结为field=null无效。
Marc B

1
第二个查询应该是正确的。您的where条款中还有哪些其他内容?
Daniel A. White

@Daniel A. White,已更新以反映更多条件的查询
Phill

Answers:


122

一条in语句将与解析相同field=val1 or field=val2 or field=val3。在其中放置一个null将归结为field=null无效。

注释马克乙

我这样做是为了聪明

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

做到了,谢谢!因此,包装字段会将这两个条件都添加到WHERE子句中?只是为了澄清
Phill Pafford

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

这样就可以消除检查中的空值。给定id_field中的空值,合并函数将代替null返回'unik_null_value',并且通过向IN列表中添加'unik_null_value,查询将返回id_field为value1-3或null的帖子。


2
稍作解释将对将来的读者有所帮助。您的代码如何帮助解决该问题?
showdev

9

丹尼尔(Daniel)回答的问题非常好。我想留下有关NULL的注释。当列包含NULL值时,我们应谨慎使用NOT IN运算符。如果您的列包含NULL值并且您使用的是NOT IN运算符,则不会获得任何输出。这是在http://www.oraclebin.com/2013/01/beware-of-nulls.html上的解释方式,这是一篇非常不错的文章,我从中发现并考虑过共享它。


不知道有多少用户使用过此问题,但是我遇到了混合null和NOT IN运算符的确切问题,并且在过去的两个小时里一直在争论。这就是人的本能……
Govind Rai

1
链接已死。
DagHøidahl'16

1
像现在还活着。
永远的学习者

3

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

当心NULLS

今天,我在使用IN和NOT IN运算符时遇到了一个非常奇怪的查询行为。实际上,我想比较两个表,找出是否table b存在from的值,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"运算符。

第一个查询:

第一个查询将在内部进行类似这样的处理。因此,anull不会在这里造成问题,因为我的前两个操作数将等于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 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

因此NULL,在使用NOT 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)

这类似于Ove Halseth使用合并的答案。
user890332

0

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.