IN子句用NULL或IS NULL

Postgres是数据库

我可以使用一个NULL值的IN子句? 例:

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

我想限制在这四个值。

我已经尝试了上面的语句,它不工作,以及它执行,但不添加与空id_fields的logging。

我也试图添加一个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 

有什么build议么?

一个in语句将被parsing为相同的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) 

由于运营商的优先级,您的查询失败。 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 ) 

OR之前添加的括号可防止AND绑定。 如果没有其他WHERE条件(不AND ),你不需要括号。 被接受的答案在这方面有点误导。

丹尼尔回答的问题是非常好的。 我想留下一个关于NULLS的说明。 当列中包含NULL值时,我们应该小心使用NOT IN运算符。 如果列中包含NULL值,并且使用NOT IN运算符,则不会得到任何输出。 这是在这里http://www.oraclebin.com/2013/01/beware-of-nulls.html的解释,这是一篇很好的文章,我曾经想过要分享它。;

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

这样你可以消除检查中的空值。 在id_field中给定一个空值,coalesce函数将返回“unik_null_value”而不是null,并且通过向IN列表添加“unik_null_value”,查询将返回id_field为value1-3或null的post。

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

当心NULLS

今天我遇到了一个非常奇怪的查询行为,同时使用IN和NOT IN运算符。 其实我想比较两个表,并找出table b是否存在一个值,并找出它的行为,如果列中包含null值。 所以我刚刚创build了一个环境来testing这种行为。

我们将创build表table_a

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

我们将创build表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_a是使用IN运算符从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值,看看上面两个查询是如何工作的。

 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"运算符,任何操作数之外的任何东西都不会给我任何输出。

 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!