微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

PostgreSQL中的(x IS NOT NULL)vs(NOT x IS NULL)

为什么x IS NOT NULL不等于NOT x IS NULL?

这段代码

CREATE TABLE bug_test (
    id int,name text
);

INSERT INTO bug_test
VALUES (1,NULL);

DO $$
DECLARE
    v_bug_test bug_test;
BEGIN
    RAISE NOTICE '%: %',v_bug_test,(v_bug_test IS NULL);
    RAISE NOTICE '%: %',(v_bug_test IS NOT NULL);
    RAISE NOTICE '%: %',(NOT v_bug_test IS NULL);

    SELECT *
    INTO v_bug_test
    FROM bug_test
    WHERE id = 1;

    RAISE NOTICE '%: %',(NOT v_bug_test IS NULL);
END
$$;

DROP TABLE bug_test;

给出以下输出

(,): t
(,): f
(,): f
(1,): f ???
(1,): t

虽然我希望得到这个输出

(,): t <<<
(1,): t
您必须区分两种情况:将一个COLUMN与NULL进行比较,或者将整个ROW(RECORD)与NULL进行比较.

请考虑以下查询

SELECT
    id,txt,txt     IS NULL AS txt_is_null,NOT txt IS NULL AS not_txt_is_null,txt IS NOT NULL AS txt_is_not_null
FROM
    (VALUES
        (1::integer,NULL::text)
    ) 
    AS x(id,txt) ;

你得到这个:

+----+-----+-------------+-----------------+-----------------+
| id | txt | txt_is_null | not_txt_is_null | txt_is_not_null | 
+----+-----+-------------+-----------------+-----------------+
|  1 |     | t           | f               | f               | 
+----+-----+-------------+-----------------+-----------------+

我想,这就是你和我的期望.您正在检查一个COLUMN对NULL,并且您得到“txt IS NOT NULL”和“NOT txt IS NULL”是等效的.

但是,如果您进行不同的检查:

SELECT
    id,x       IS NULL AS x_is_null,NOT x   IS NULL AS not_x_is_null,x   IS NOT NULL AS x_is_not_null
FROM
    (VALUES
        (1,NULL)
    ) 
    AS x(id,txt) ;

然后你得到

+----+-----+-----------+---------------+---------------+
| id | txt | x_is_null | not_x_is_null | x_is_not_null |
+----+-----+-----------+---------------+---------------+
|  1 |     | f         | t             | f             |
+----+-----+-----------+---------------+---------------+

这可能是令人惊讶的.一件事看起来合理(x IS NULL)和(NOT x IS NULL)是彼此相反的.另一件事(事实上既不是“x IS NULL”也不是“x IS NOT NULL”都是真的),看起来很奇怪.

然而,这就是PostgreSQL documentation所说的应该发生的事情:

If the expression is row-valued,then IS NULL is true when the row expression itself is null or when all the row’s fields are null,while IS NOT NULL is true when the row expression itself is non-null and all the row’s fields are non-null. Because of this behavior,IS NULL and IS NOT NULL do not always return inverse results for row-valued expressions; in particular,a row-valued expression that contains both null and non-null fields will return false for both tests. In some cases,it may be preferable to write row IS disTINCT FROM NULL or row IS NOT disTINCT FROM NULL,which will simply check whether the overall row value is null without any additional tests on the row fields.

我必须承认我不认为我曾经使用过针对null的行值比较,但我想如果可能存在,那么可能会有一些用例.无论如何,我认为这不常见.

原文地址:https://www.jb51.cc/postgresql/192225.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐