【问题标题】:Postgres excludes NULL in WHERE id != int queryPostgres 在 WHERE id != int 查询中排除 NULL
【发布时间】:2019-01-17 13:00:34
【问题描述】:

昨天我在 Postgres 中尝试从统计表中过滤掉用户 ID 时遇到了一个奇怪的问题。例如,当我们这样做时,user_id != 24,postgres 也排除了user_idNULL 的行。

我创建了以下显示相同结果的测试代码。

CREATE TEMPORARY TABLE test1 (
    id int DEFAULT NULL
);

INSERT INTO test1 (id) VALUES (1), (2), (3), (4), (5), (2), (4), (6), 
    (4), (7), (5), (9), (5), (3), (6), (4), (3), (7), 
    (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL);     

SELECT COUNT(*) FROM test1;

SELECT id, COUNT(*) as count
FROM test1
GROUP BY id;

SELECT id, COUNT(*) as count
FROM test1
WHERE id != 1
GROUP BY id;

SELECT id, COUNT(*) as count
FROM test1
WHERE (id != 1 OR id IS NULL)
GROUP BY id;

第一个查询只计算所有行。 第二个计算每个值的数量,包括空值。 第三个不包括值 1 以及所有空值。 第四种是排除值 1 并仍然包含空值的解决方法。

对于我尝试使用此查询的内容,应始终包含空值。

解决方法是做到这一点的唯一方法吗?这是预期的 Postgres 行为吗?

【问题讨论】:

    标签: postgresql null where


    【解决方案1】:

    您的“解决方法”是通常的方法。一切都按预期运行。

    原因很简单:空值既不等于也不等于任何东西。当您认为 null 表示“未知”时,这是有道理的,并且与未知值进行比较的真实性也是未知的。

    推论是:

    • null = null 不正确
    • null = some_value 不正确
    • null != some_value 不正确

    存在两个特殊的比较 IS NULLIS NOT NULL 来处理测试列是否为null。没有其他与 null 的比较是真的。

    【讨论】:

    • 谢谢 Bohemian,我想它确实有道理,正如你所说,如果它是未知的。
    • 感谢您解释这些比较行为为何如此。
    【解决方案2】:

    IS DISTINCT FROM 谓词就是为此目的而存在的。它是这样描述的:

    不相等,把 null 当作普通值处理

    所以只做id IS DISTINCT FROM 1 应该可以工作。

    参考:https://www.postgresql.org/docs/11/functions-comparison.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多