我在Redshift上查询一些结果,当我检查两个整数列之间的不相等时,偶然发现了什么似乎是一个错误,当一些结果为其中一个列的值为NULL时。
这是一个简单的测试:
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,我得到了相同的结果。答案 0 :(得分:2)
Null被视为未知值。当您比较1 != null
时,结果将被评估为false。
因此,在1 != 2
答案 1 :(得分:0)
正如VK_217所说,这是因为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)
)
答案 2 :(得分:0)
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)