检查两个整数列之间的不相等将返回错误的结果

xfyts7mz  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(371)

我正在查询一些关于红移的结果,当我检查两个整型列之间的不相等性时,偶然发现了一个错误,当一些结果中的一个列有空值时。
下面是一个简单的测试:

WITH test AS (
    SELECT 1 AS orig, 1 AS dest UNION
    SELECT 1 AS orig, 2 AS dest UNION
    SELECT 1 AS orig, NULL AS dest
)
SELECT COUNT(*) FROM test WHERE orig != dest

我显然希望结果是 2 ,但它会打印出来 1 .
这种行为的原因是什么?
谢谢
编辑:刚刚检查了mysql,我得到了相同的结果。

2cmtqfgy

2cmtqfgy1#

mysql和redshift都提供 COALESCE 可以在可能存在空值的情况下使用的函数。此查询将为您提供预期结果。

-- 9999999 value used below is a value sure not to exist in other table.
-- can be 0 or any value you choose based on your a prioiri knowledge of the data

WITH test AS (
    SELECT 1 AS orig, 1 AS dest UNION
    SELECT 1 AS orig, 2 AS dest UNION
    SELECT 1 AS orig, NULL AS dest
)
SELECT COUNT(*) FROM test WHERE orig != COALESCE(dest,999999999)
kognpnkq

kognpnkq2#

null被视为未知值。比较时 1 != null 结果被评估为false。
因此,在您的情况下,结果是1 1 != 2

mpbci0fu

mpbci0fu3#

正如vkÙu所说,这是由于null不被视为一个值,并且不能与现有值进行比较,因此任何类型的比较都将返回null(因此,与where子句不匹配)。
您可以在本文中找到有关该行为的更多详细信息:https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
如果你需要有预期的行为,以下是我最终使用的:

WITH test AS (
    SELECT 1 AS orig, 1 AS dest UNION
    SELECT 1 AS orig, 2 AS dest UNION
    SELECT 1 AS orig, NULL AS dest
)
SELECT COUNT(*) FROM test WHERE (
    (orig IS NULL AND dest IS NOT NULL)
    OR
    (orig IS NOT NULL AND dest IS NULL)
    OR
    (orig != dest)
)

相关问题