为什么 null 不等于 null false
我正在读这篇文章: 在 SQL 中获取 null == null
共识是,当尝试测试之间的相等性时两个(可为空的)sql 列,正确的方法是:
where ((A=B) OR (A IS NULL AND B IS NULL))
当 A 和 B 为 NULL 时,(A=B) 仍返回 FALSE,因为 NULL 不等于 NULL。这就是为什么需要额外检查的原因。
测试不等式时怎么样?根据上面的讨论,它让我认为要测试不等式,我需要做类似的事情:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
但是,我注意到这是没有必要的(至少在 informix 11.5 上不是),我可以这样做:
where (A<>B)
如果 A 和 B为 NULL,则返回 FALSE。如果 NULL 不等于 NULL,那么这不应该返回 TRUE 吗?
编辑
这些都是很好的答案,但我认为我的问题有点模糊。请允许我重新表述一下:
鉴于 A 或 B 可以为 NULL,是否足以检查它们的不等式
where (A<>B)
或者我是否需要像这样显式检查它:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
请参阅此 线程来回答这个问题。
I was reading this article:
Get null == null in SQL
And the consensus is that when trying to test equality between two (nullable) sql columns, the right approach is:
where ((A=B) OR (A IS NULL AND B IS NULL))
When A and B are NULL, (A=B) still returns FALSE, since NULL is not equal to NULL. That is why the extra check is required.
What about when testing inequalities? Following from the above discussion, it made me think that to test inequality I would need to do something like:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
However, I noticed that that is not necessary (at least not on informix 11.5), and I can just do:
where (A<>B)
If A and B are NULL, this returns FALSE. If NULL is not equal to NULL, then shouldn't this return TRUE?
EDIT
These are all good answers, but I think my question was a little vague. Allow me to rephrase:
Given that either A or B can be NULL, is it enough to check their inequality with
where (A<>B)
Or do I need to explicitly check it like this:
WHERE ((A <> B) OR (A IS NOT NULL AND B IS NULL) OR (A IS NULL AND B IS NOT NULL))
REFER to this thread for the answer to this question.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
因为该行为遵循已建立的三元逻辑,其中 NULL 被视为未知值。
如果您将 NULL 视为未知,那么它会变得更加直观:
unknown a
等于unknown b
吗?没有办法知道,所以:未知
。Because that behavior follows established ternary logic where NULL is considered an unknown value.
If you think of NULL as unknown, it becomes much more intuitive:
Is
unknown a
equal tounknown b
? There's no way to know, so:unknown
.涉及 NULL 的关系表达式实际上再次产生 NULL
编辑,
这里,
<>
代表任意二元运算符,NULL
是 SQL 占位符,< code>value 是任何值(NULL
不是值):NULL <>值
->NULL
NULL <> NULL
->NULL
的逻辑是:
NULL
表示“无值”或“未知值”,因此与任何实际值的任何比较都是没有意义的。如果您不知道
X
持有什么值(如果有),X = 42
是真、假还是未知? SQL 说它是未知的。 X = Y 是真、假还是未知(假设两者都是未知的)? SQL 表示结果未知。对于任何二元关系操作来说都是如此,这只是逻辑上的(即使模型中本来就不存在 NULL)。SQL 还提供了两个一元后缀运算符,
IS NULL
和IS NOT NULL
,它们根据其操作数返回 TRUE 或 FALSE。NULL 是 NULL
->TRUE
NULL IS NOT NULL
->假
relational expressions involving NULL actually yield NULL again
edit
here,
<>
stands for arbitrary binary operator,NULL
is the SQL placeholder, andvalue
is any value (NULL
is not a value):NULL <> value
->NULL
NULL <> NULL
->NULL
the logic is:
NULL
means "no value" or "unknown value", and thus any comparison with any actual value makes no sense.is
X = 42
true, false, or unknown, given that you don't know what value (if any)X
holds? SQL says it's unknown. isX = Y
true, false, or unknown, given that both are unknown? SQL says the result is unknown. and it says so for any binary relational operation, which is only logical (even if having NULLs in the model is not in the first place).SQL also provides two unary postfix operators,
IS NULL
andIS NOT NULL
, these return TRUE or FALSE according to their operand.NULL IS NULL
->TRUE
NULL IS NOT NULL
->FALSE
所有涉及
null
的比较都是未定义的,并且计算结果为 false。这个想法阻止null
被评估为等同于null
,也阻止null
被评估为不等同于null< /代码>。
All comparisons involving
null
are undefined, and evaluate to false. This idea, which is what preventsnull
being evaluated as equivalent tonull
, also preventsnull
being evaluated as NOT equivalent tonull
.简短的答案是......NULL 很奇怪,它们的行为并不像您期望的那样。
这是一篇关于 NULL 在 SQL 中如何工作的精彩论文。我认为这将有助于提高您对该主题的理解。我认为有关处理表达式中的空值的部分对您特别有用。
http://www.oracle.com/technology/oramag/ oracle/05-jul/o45sql.html
The short answer is... NULLs are weird, they don't really behave like you'd expect.
Here's a great paper on how NULLs work in SQL. I think it will help improve your understanding of the topic. I think the sections on handling null values in expressions will be especially useful for you.
http://www.oracle.com/technology/oramag/oracle/05-jul/o45sql.html
表达式中空值的默认 (ANSI) 行为将导致空值(对于这种情况,还有足够多的其他答案)。
然而,在处理 MS Sql Server 时,我会提出一些未列出的极端情况和警告。
在 SQL Server 中可以使用 SET ANSI_NULLS OFF 覆盖有关特定 Null = Null 测试的表达式逻辑,然后将给你空值之间的相等性 - 这不是推荐的举动,但确实存在。
The default (ANSI) behaviour of nulls within an expression will result in a null (there are enough other answers with the cases of that).
There are however some edge cases and caveats that I would place when dealing with MS Sql Server that are not being listed.
It is possible in SQL Server to override the expression logic regarding the specific Null = Null test, using the SET ANSI_NULLS OFF, which will then give you equality between null values - this is not a recommended move, but does exist.
这是一个快速修复
ISNULL(A,0)=ISNULL(B,0)
0 可以更改为数据中永远不会发生的内容
Here is a Quick Fix
ISNULL(A,0)=ISNULL(B,0)
0 can be changed to something that can never happen in your data
“未知a等于未知b吗?没有办法知道,所以:未知。”
问题是:为什么比较结果为 FALSE?
给定三值逻辑,比较产生 UNKNOWN (不是 FALSE)确实是明智的。但 SQL 确实会产生 FALSE,而不是 UNKNOWN。
SQL 语言中无数的错误之一。
此外,必须考虑以下因素:
如果“未知”是三元逻辑中的逻辑值,那么应该是两个碰巧都是“未知”(的值)的逻辑值之间的相等比较的情况,那么该比较应该产生 TRUE。
如果逻辑值本身是未知的,那么显然不能通过将值“未知”放在那里来表示,因为这意味着逻辑值是已知的(“未知”)。也就是说,关系理论如何证明实现 3 值逻辑会提出对 4 值逻辑的需求,4 值逻辑会导致对 5 值逻辑的需求,等等,无穷无尽。
"Is unknown a equal to unknown b? There's no way to know, so: unknown."
The question was : why does the comparison yield FALSE ?
Given three-valued logic, it would indeed be sensible for the comparison to yield UNKNOWN (not FALSE). But SQL does yield FALSE, and not UNKNOWN.
One of the myriads of perversities in the SQL language.
Furthermore, the following must be taken into account :
If "unkown" is a logical value in ternary logic, then it ought to be the case that an equality comparison between two logical values that both happen to be (the value for) "unknown", then that comparison ought to yield TRUE.
If the logical value is itself unknown, then obviously that cannot be represented by putting the value "unknown" there, because that would imply that the logical value is known (to be "unknown"). That is, a.o., how relational theory proves that implementing 3-valued logic raises the requirement for a 4-valued logic, that a 4 valued logic leads to the need for a 5-valued logic, etc. etc. ad infinitum.