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的行值比较,但我想如果可能存在,那么可能会有一些用例.无论如何,我认为这不常见.

相关文章

项目需要,有个数据需要导入,拿到手一开始以为是mysql,结果...
本文小编为大家详细介绍“怎么查看PostgreSQL数据库中所有表...
错误现象问题原因这是在远程连接时pg_hba.conf文件没有配置正...
因本地资源有限,在公共测试环境搭建了PGsql环境,从数据库本...
wamp 环境 这个提示就是说你的版本低于10了。 先打印ph...
psycopg2.OperationalError: SSL SYSCALL error: EOF detect...