sql - 如何找到两个值不同且其中一个可以为 NULL 的行?为什么 NULL != 1 是假的?

标签 sql postgresql

在 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 fromis not distinct from 。 Postgres 恰好是少数几个实际实现此运算符的数据库之一,但 SQL 确实有适当的比较运算符来等于 NULL .

关于sql - 如何找到两个值不同且其中一个可以为 NULL 的行?为什么 NULL != 1 是假的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61385072/

相关文章:

sql - 如何限制 MERGE 语句中 OUTPUT 子句的操作?

sql - 我有一个以奇怪的方式失败的删除插入 CTE

sql - SQL Server 中的 pivot varchar 列?

java - Spring Boot 在多个数据库(数据源)之间切换

postgresql - postgres 函数丢失列名

sql - 使用命名实例伪造默认实例?

c# - SQL Server 和 C# 中每条记录的字符串处理

macos - 在 Mac Lion 上安装 Postgresql

sql - 主键列的外键约束 - 问题?

sql - 如何在 Rails 控制台中测试添加索引的性能?