我没有问,如果它.我知道事实并非如此.
我很好奇原因.我已经阅读了支持文档,例如关于在MySQL中使用Nulls的支持文档,但它们并没有给出任何理由.他们只重复你必须使用的"是空"的口头禅.
这一直困扰着我.在进行动态SQL(那些必须要做的极少数时间)时,将"null"传递给where子句会更容易:
@where = "where GroupId = null"
Run Code Online (Sandbox Code Playgroud)
这将是常规变量的简单替换.相反,我们必须使用if/else块来执行以下操作:
if @groupId is null then
@where = "where GroupId is null"
else
@where = "where GroupId = @groupId"
end
Run Code Online (Sandbox Code Playgroud)
在更大更复杂的查询中,这是一个巨大的痛苦.有没有特定的原因,SQL和所有主要的RDBMS供应商都不允许这样做?它会产生某种关键字冲突或价值冲突?
编辑:
许多答案的问题(在我看来)是每个人都在设置null和"我不知道它的值是什么"之间的等价.这两件事之间存在巨大差异.如果null意味着"有一个值,但它是未知的"我会100%同意空值不能相等.但SQL null并不意味着.这意味着没有价值.任何两个为null的SQL结果都没有值. 没有价值不等于未知价值.两件不同的事情.这是一个重要的区别.
编辑2:
我遇到的另一个问题是其他HLL允许null = null完全正常并适当地解决它.例如,在C#中,null = null返回true.
And*_*mar 22
它默认是关闭的原因null
是null
在商业意义上真的不等于它.例如,如果您要加入订单和客户:
select * from orders o join customers c on c.name = o.customer_name
Run Code Online (Sandbox Code Playgroud)
将未知客户的订单与名称未知的客户进行匹配是没有意义的.
大多数数据库允许您自定义此行为.例如,在SQL Server中:
set ansi_nulls on
if null = null
print 'this will not print'
set ansi_nulls off
if null = null
print 'this should print'
Run Code Online (Sandbox Code Playgroud)
平等是可以绝对确定的.麻烦的null
是,它本身就是未知数.如果你遵循真值表的三值逻辑,null
结合任何其他值是null
- 未知.问SQL"我的值是否等于 null?" 即使输入为空,每次都是未知的.我认为实施表明IS NULL
了这一点.
这是一种语言语义.
空缺是缺乏价值.
is null
我感觉合理.它说,"缺乏价值"或"未知".我个人从来没有问过某人是否"等于缺乏价值".
我不禁感到您对到目前为止给出的答案仍然不满意,所以我想我会尝试另一种方法。让我们举一个例子(不,我不知道为什么这个特定的例子会出现在我的脑海中)。
我们为员工准备了一张桌子EMP
:
EMP
---
EMPNO GIVENNAME
E0001 Boris
E0002 Chris
E0003 Dave
E0004 Steve
E0005 Tony
Run Code Online (Sandbox Code Playgroud)
而且,无论出于何种奇怪的原因,我们都在跟踪每位员工在特定日期选择穿什么颜色的裤子 ( TROUS
):
TROUS
-----
EMPNO DATE COLOUR
E0001 20110806 Brown
E0002 20110806 Blue
E0003 20110806 Black
E0004 20110806 Brown
E0005 20110806 Black
E0001 20110807 Black
E0003 20110807 Black
E0004 20110807 Grey
Run Code Online (Sandbox Code Playgroud)
我可以继续。我们写了一个查询,我们想知道每个员工的名字,以及他们在 8 月 7 日穿的是什么颜色的裤子:
SELECT e.GIVENNAME,t.COLOUR
FROM
EMP e
LEFT JOIN
TROUS t
ON
e.EMPNO = t.EMPNO and
t.DATE = '20110807'
Run Code Online (Sandbox Code Playgroud)
我们得到结果集:
GIVENNAME COLOUR
Chris NULL
Steve Grey
Dave Black
Boris Black
Tony NULL
Run Code Online (Sandbox Code Playgroud)
现在,这个结果集可能在视图、CTE 或其他任何东西中,我们可能想继续使用 SQL 询问有关这些结果的问题。其中一些问题可能是什么?
戴夫和鲍里斯那天穿的是同一种颜色的裤子吗?(是的,黑色==黑色)
戴夫和史蒂夫那天穿的是同一种颜色的裤子吗?(不,黑色!=灰色)
那天鲍里斯和托尼穿的是同一种颜色的裤子吗?(未知 - 我们正在尝试与 NULL 进行比较,并且我们遵循 SQL 规则)
鲍里斯和托尼那天穿的裤子不是同色的吗?(未知 - 我们再次与 NULL 进行比较,并且我们遵循 SQL 规则)
那天克里斯和托尼穿的是同一种颜色的裤子吗?(未知)
请注意,IS NULL
如果您将数据库设计为从不使用 NULL 作为丢失信息的标记,那么您已经了解特定机制(例如)来强制您想要的结果。
但是在 SQL 中,NULL 被赋予了两个角色(至少)——标记不适用的信息(也许我们数据库中有完整的信息,而 Chris 和 Tony 那天没有上班,或者上班但没有穿裤子),并标记丢失的信息(克里斯那天确实出现了,我们只是此时数据库中没有记录信息)
如果您NULL
纯粹将其用作不适用信息的标记,我假设您正在避免诸如外连接之类的构造。
我觉得有趣的是,您NaN
对其他答案提出了评论,而没有看到它NaN
和 (SQL)NULL
有很多共同点。它们之间最大的区别在于NULL
,无论涉及什么数据类型,都旨在跨系统使用。
您最大的问题似乎是您已经确定 NULL 在所有编程语言中具有单一含义,并且您似乎觉得 SQL 已经破坏了该含义。事实上,不同语言中的 null 经常具有微妙的不同含义。在某些语言中,它是 0 的同义词。在其他语言中,则不是,因此比较在某些语言中0==null
会成功,而在其他语言中会失败。您提到了 VB,但 VB(假设您说的是 .NET 版本)没有 null。它有Nothing
,这又是微妙的不同(它在 C# 构造的大多数方面都是等价的default(T)
)。
因为在ANSI SQL中,null的意思是“未知”,它不是一个值。因此,它不等于任何东西;您可以只评估值的状态(已知或未知)。