106

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

有什么建议么?

4

7 回答 7

156

语句将in被解析为field=val1 or field=val2 or field=val3. 在那里放一个空值将归结为field=null不起作用。

(马克B评论

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

SELECT *
FROM tbl_name
WHERE 
(id_field IN ('value1', 'value2', 'value3') OR id_field IS NULL)
于 2011-06-15T18:05:31.773 回答
26

由于运算符优先级,您的查询失败。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),则不需要额外的括号。在这方面,公认的答案具有误导性。

于 2013-02-11T06:45:48.313 回答
23
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 的帖子。

于 2016-09-12T14:31:30.323 回答
12

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

于 2013-02-11T04:56:38.490 回答
8

注意:由于有人声称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_bIN

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 的数据中table_b。我们null在表中引入了一个值。但它怎么会这样呢?让我们将两个查询拆分为"AND"and"OR"运算符。

第一个查询:

第一个查询将在内部处理,如下所示。所以 anull不会在这里产生问题,因为我的前两个操作数将评估为trueor 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_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

谨防空!!

于 2017-10-05T07:03:20.017 回答
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)
于 2018-01-24T18:51:16.780 回答
0

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

于 2020-01-02T16:01:47.803 回答