【问题标题】:Why does null equal integer in WHERE?为什么 null 在 WHERE 中等于整数?
【发布时间】:2023-03-19 01:43:01
【问题描述】:

我正在使用普通连接进行查询,目的是找到用户尚未投票的最新记录:

SELECT
    v.user_id,
    v.version_id,
    vv.user_id
FROM versions v
LEFT JOIN versions_votes vv ON v.version_id = vv.version_id
WHERE vv.user_id != 39;

奇怪的是,如果 vv.user_id 为空,这不会返回任何行。我公认的对这个问题的行人理解是 NULL 不能等于任何东西 - 这就是为什么我们有首先测试IS NULL 而不是=NULL

然而,我们在这里 - 如果我修改 WHERE 子句如下:

WHERE (vv.user_id != 39 OR vv.user_id IS NULL)

查询似乎工作正常(并且似乎确认NULL 正在评估为 39。

【问题讨论】:

  • statuscreated 来自哪里?请澄清并(始终)添加您的 Postgres 版本。
  • 这个问题可能会提供一些见解:stackoverflow.com/questions/5658457/… 底线 其中一个运算符为 NULL 使表达式评估为 FALSE
  • 我认为 Bob 在这里得到了它 - 因为我正在做一个 != 比较,它会以他建议的方式对一侧的 NULL 做出反应,我没有考虑到这一点。
  • statuscreated 来自 versions,但不相关 - 正如我所说,如果我通过 OR 测试 NULL,则查询的行为符合预期。
  • @sudowned:每一列的来源总是相关。即使这些列似乎与您无关。这需要在问题中明确。

标签: sql postgresql null left-join


【解决方案1】:

NULL cannot be equal to anything你说得对。
你缺少的是NULL cannot be unequal, either

NULL 与任何东西相比总是NULL。手头的问题是你弄错了LEFT JOIN。这应该有效:

SELECT v.user_id, v.version_id, vv.user_id
FROM   versions v
LEFT   JOIN versions_votes vv ON v.version_id = vv.version_id
                             AND vv.user_id = 39
WHERE  vv.version_id IS NULL
ORDER  BY v.created
LIMIT  1;

您在WHERE 子句中有一个引用vv 的附加条件:AND vv.user_id != 39。可能期望NULL != 39 符合条件,但事实并非如此。此相关答案中的更多详细信息:
Query with LEFT JOIN not returning rows for count of 0

基本上有三种技术可以做到这一点:
Select rows which are not present in other table

【讨论】:

  • @wildplasser:确实如此。
  • 也许三值逻辑毕竟不是一个好主意。但缺点是:人们会实施自己的系统。很糟糕。和/或因此不强制执行。
猜你喜欢
  • 2010-12-22
  • 2020-04-27
  • 2018-10-08
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 2010-12-13
  • 2011-09-05
  • 2011-03-09
相关资源
最近更新 更多