在 Postgres 中,我想查找其中一列与另一列不同的行。令我惊讶的是, 1 != NULL 的比较产生 NULL,我猜这是一个虚假值,并且它不包含在结果中。
SELECT * FROM (VALUES
(0, 0),
(0, 1),
(1, 0),
(1, 1),
(0, NULL),
(1, NULL),
(NULL, 0),
(NULL, 1),
(NULL, NULL)
) v (x, y)
WHERE x != y
结果:
x y
0 1
1 0
这里是演示该问题的在线 SQL fiddle : https://www.db-fiddle.com/f/hTbJQJw36k3KrrJfUASpn9/0
我确实发现,当将任何内容与 null 进行比较时,结果始终为 null,这就是 it's supposed to work 的原因。 .
因此,当我询问 WHERE x = y IS NOT TRUE
时,我可以更接近一点:
SELECT *, (x!=y) AS comp, (x=y IS NOT TRUE) AS not_true FROM (VALUES
(0, 0),
(0, 1),
(1, 0),
(1, 1),
(0, NULL),
(1, NULL),
(NULL, 0),
(NULL, 1),
(NULL, NULL)
) v (x, y)
x y comp not_true
0 0 false false
0 1 true true
1 0 true true
1 1 false false
0 null null true
1 null null true
null 0 null true
null 1 null true
null null null true
我希望最后一行是真的。我知道我正在将任何内容与 NULL 进行比较,因此得到 NULL 这不是 TRUE,所以是的。
我可以编写一个额外的条件,例如 WHERE (x = y IS NOT TRUE AND (x IS NOT NULL OR y IS NOT NULL))
,但这似乎过于复杂。这是更新后的 SQL fiddle :
https://www.db-fiddle.com/f/hTbJQJw36k3KrrJfUASpn9/1
有没有更简单的方法?
最佳答案
您可以使用NULL
安全比较运算符:
where x is distinct from y
Here是一个数据库<> fiddle 。
关于你的“为什么”问题。 NULL
在 SQL 中具有明确定义的语义(含义)。这意味着该值未知。因此,几乎所有比较都会返回 NULL
(“未知”)。表达式1 <> NULL
计算结果为 NULL
,因为NULL
可能是 1
-- 或任何其他值。
SQL 标准还实现了处理此问题的功能 is distinct from
和is not distinct from
。 Postgres 恰好是少数几个实际实现此运算符的数据库之一,但 SQL 确实有适当的比较运算符来等于 NULL
.
关于sql - 如何找到两个值不同且其中一个可以为 NULL 的行?为什么 NULL != 1 是假的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61385072/