带有 NULL 或 IS NULL 的 IN 子句
Posted
技术标签:
【中文标题】带有 NULL 或 IS NULL 的 IN 子句【英文标题】:IN Clause with NULL or IS NULL 【发布时间】:2011-09-15 18:26:19 【问题描述】: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
有什么建议吗?
【问题讨论】:
in
语句的解析方式与 field=val1 or field=val2 or field=val3
相同。将 null 放在那里将归结为 field=null
这将不起作用。
第二个查询应该是对的。您的where
子句中还有哪些其他内容?
@Daniel A. White,更新以反映更多条件的查询
【参考方案1】:
in
语句的解析方式与field=val1 or field=val2 or field=val3
相同。将 null 放在那里将归结为field=null
这将不起作用。
(CommentMarc B)
我会这样做是为了清晰
SELECT *
FROM tbl_name
WHERE
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
【讨论】:
啊,成功了,谢谢!那么包装字段会将两个条件都添加到 WHERE 子句中吗?只是为了澄清 @Phill - 这是一个操作顺序问题。【参考方案2】:由于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
),则不需要额外的括号。接受的答案在这方面具有误导性。
【讨论】:
【参考方案3】: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 的帖子。
【讨论】:
稍微解释一下会对以后的读者有所帮助。您的代码如何帮助解决问题? 来自文档:COALESCE() 函数返回列表中的第一个非空值。因此,当 id_field 为 null 时,将返回 'unik_null_value' 并查询返回正确的记录。【参考方案4】:丹尼尔回答的问题非常好。我想留下关于 NULLS 的说明。当列包含 NULL 值时,我们应该小心使用 NOT IN 运算符。如果您的列包含 NULL 值并且您使用的是 NOT IN 运算符,您将不会得到任何输出。这就是在这里http://www.oraclebin.com/2013/01/beware-of-nulls.html 的解释方式,这是一篇非常好的文章,我偶然发现并想分享它。
【讨论】:
不确定有多少用户遇到过这个问题,但我遇到了混合空值和 NOT IN 运算符的确切问题,并且在过去两个小时内一直在胡乱讨论。这是perp ... 链接已失效。 现在还活着。【参考方案5】:注意:由于有人声称 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
中的值是否存在,方法是使用 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
不会在这里产生问题,因为我的前两个操作数将评估为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 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!!
【讨论】:
优秀的答案。我刚刚在工作中发现了这个问题。 Oracle 非常非常奇怪的行为。【参考方案6】:我知道回答晚了,但可能对其他人有用 您可以使用子查询并将 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 使用合并的答案。【参考方案7】:Null
表示缺少数据。 Null
正式定义为不可用、未分配、未知或不适用的值(OCA Oracle Database 12c,SQL Fundamentals I Exam Guide,p87)。
因此,当使用“in”或“not in”子句限制所述列时,您可能看不到列包含空值的记录。
【讨论】:
以上是关于带有 NULL 或 IS NULL 的 IN 子句的主要内容,如果未能解决你的问题,请参考以下文章
WHERE IS NULL、IS NOT NULL 或 NO WHERE 子句取决于 SQL Server 参数值
SQL Server:查询应用在 where 子句中,包含 Json 对象的列上的 IS NOT Null 需要更多时间