我不是在问 。我知道事实并非如此。
我很好奇。我已经阅读了支持文档,例如on Working With Nulls in MySQL,但它们并没有给出任何理由。他们只重复你必须使用的“是空”的咒语。
这一直困扰着我。在进行动态SQL时(那些必须要做的极少数情况),将“null”传递给where子句会更容易:
@where = "where GroupId = null"
这将是常规变量的简单替换。相反,我们必须使用if / else块来执行以下操作:
if @groupId is null then
@where = "where GroupId is null"
else
@where = "where GroupId = @groupId"
end
在更大的更复杂的查询中,这是一个巨大的痛苦。有没有特定的原因,SQL和所有主要的RDBMS供应商都不允许这样做?它会创建某种关键字冲突或价值冲突吗?
修改
许多答案的问题(在我看来)是每个人都在设置null和“我不知道它的值是什么”之间的等价。这两件事之间存在巨大差异。如果null意味着“有一个值,但它是未知的”我会100%同意空值不能相等。但SQL null并不意味着。这意味着没有值。任何两个为null的SQL结果都没有值。 否值不等于未知值。两件不同的事情。这是一个重要的区别。
编辑2:
我遇到的另一个问题是其他HLL允许null = null完全正常并适当地解决它。例如,在C#中,null = null返回true。
答案 0 :(得分:21)
默认情况下关闭的原因是null
在商业意义上确实不等于null
。例如,如果您要加入订单和客户:
select * from orders o join customers c on c.name = o.customer_name
将未知客户的订单与名称不明的客户进行匹配是没有多大意义的。
大多数数据库允许您自定义此行为。例如,在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'
答案 1 :(得分:9)
平等是可以绝对确定的。 null
的问题在于它本身就是未知数。如果您按照真值表的三值逻辑,null
与任何其他值相结合null
- 未知。问SQL“我的值等于 null吗?”即使输入为空,也会每次都IS NULL
的实施表明了这一点。
答案 2 :(得分:5)
这是一种语言语义。
Null是缺乏价值。
is null
对我有意义。它说,“缺乏价值”或“未知”。就个人而言,我从未问过某人是否“等于缺乏价值”。
答案 3 :(得分:4)
我不禁觉得你对目前给出的答案仍然不满意,所以我想我会尝试另一种方法。让我们举个例子(不,我不知道为什么这个具体的例子已经出现在我的脑海中)。
我们有一个员工表,EMP
:
EMP
---
EMPNO GIVENNAME
E0001 Boris
E0002 Chris
E0003 Dave
E0004 Steve
E0005 Tony
而且,无论出于何种奇怪的原因,我们都会追踪每个员工在特定日期选择穿的颜色裤子(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
我可以继续。我们写了一个查询,我们想知道每个员工的名字,以及他们在8月7日穿的是什么颜色的裤子:
SELECT e.GIVENNAME,t.COLOUR
FROM
EMP e
LEFT JOIN
TROUS t
ON
e.EMPNO = t.EMPNO and
t.DATE = '20110807'
我们得到结果集:
GIVENNAME COLOUR
Chris NULL
Steve Grey
Dave Black
Boris Black
Tony NULL
现在,这个结果集可以在视图中,或者CTE中,或者其他什么,我们可能希望继续使用SQL来询问有关这些结果的问题。这些问题可能是什么?
那天戴夫和鲍里斯穿着同色系的裤子? (是的,黑色==黑色)
戴夫和史蒂夫当天穿着同样颜色的裤子? (不,黑!=灰色)
那天鲍里斯和托尼穿着同样颜色的裤子? (未知 - 我们试图与NULL进行比较,我们遵循SQL规则)
鲍里斯和托尼不当天穿着同色系的裤子? (未知 - 我们再次与NULL进行比较,我们遵循SQL规则)
那天克里斯和托尼穿着同色系的裤子? (未知)
请注意,如果您将数据库设计为永远不会使用NULL作为缺失信息的标记,那么您已经了解了强制所需结果的特定机制(例如IS 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)
的大多数方面都相同)。
答案 4 :(得分:3)
概念是NULL不是公平值。它表示没有值。
因此,只有变量或列IS NULL
才会被检查,但如果IS EQUAL TO NULL
则不能。
打开算术比较后,您可能需要与IS GREATER THAN NULL
或IS LESS THAN OR EQUAL TO NULL
答案 5 :(得分:3)
NULL未知。这既不是真的也不是假的,所以当你将任何事情与未知事物进行比较时,唯一的答案就是“未知”维基百科上更好的文章http://en.wikipedia.org/wiki/Null_(SQL)
答案 6 :(得分:2)
因为在ANSI SQL中,null表示“未知”,这不是值。因此,它不等于任何东西;你可以只评估价值的状态(已知或未知)。
答案 7 :(得分:2)
一个。 Null不是“缺乏价值”
湾Null不是“空”
℃。 Null不是“未设置值”
以上都是,而且都不是。
根据技术权利,NULL是“未知值”。但是,就像C / C ++中未初始化的指针一样,你并不知道你指的是什么。对于数据库,它们分配空间但不初始化该空间中的值。
因此,它是一个“空”空间,因为它没有被初始化。如果将值设置为NULL,则原始值将保留在该存储位置。如果它原来是一个空字符串(例如),它将保持原样。
这是一个“缺乏价值”的事实,它没有被设置为数据库认为有效的值。
这是一个“未设置的值”,因为如果刚刚分配了空间,那里的值从未设置过。
“未知”是我们在检查NULL时真正了解的最接近的事情。
因此,如果我们尝试比较这个“未知”值,我们将得到一个比较
a)可能有效也可能无效
b)可能有也可能没有我们期望的结果
c)可能会或可能不会使数据库崩溃。
因此,DBMS系统(很久以前)认为在NULL方面使用相等甚至没有意义。
因此,“= null”毫无意义。
答案 8 :(得分:1)
除了已经说过的所有内容之外,我想强调你在第一行写的内容是错误的。 SQL 支持“= NULL”语法,但它具有与“IS NULL”不同的语义 - 正如您链接到的那篇文档中所示。
答案 9 :(得分:1)
我同意OP
where column_name = null
应语法糖
where column_name is null
但是,我确实理解为什么SQL的创建者想要区分它们。在三值逻辑中(IMO这是用词不当),谓词可以返回两个值( true 或 false )或 unknown ,这在技术上是不仅仅是一种价值,而只是一种表达方式,我们不知道这两个价值中的哪一个是"。根据三值逻辑考虑以下谓词:
A == B
这个谓词测试A是否等于B.这是真值表的样子:
T U F
-----
T | T U F
U | U U U
F | F U T
如果A或B未知,谓词本身总是返回未知,无论另一个是真还是假或未知。
在SQL中,null是 unknown 的同义词。所以,SQL谓词
column_name = null
测试column_name的值是否等于其值未知的值,并且无论column_name是true还是false或者是否为其他任何内容,都返回unknown,就像上面的三值逻辑一样。 SQL DML操作仅限于对where子句中的谓词返回true的行进行操作,忽略谓词返回false或unknown的行。这就是为什么"其中column_name = null"不对任何行进行操作。
答案 10 :(得分:0)
NULL不等于NULL。它不能等于NULL。 没有意义让他们平等。
考虑它的几种方法:
想象一下一个联系人数据库,其中包含FirstName
,LastName
,DateOfBirth
和HairColor
等字段。如果我查找记录WHERE DateOfBirth = HairColor
,它是否应匹配任何内容?如果有人的DateOfBirth
为空,而他们的HairColor
也是如此,该怎么办?未知的头发颜色不等于未知的其他任何。
让我们将联系人表格与购买和产品表一起加入。假设我想找到一个客户购买假发的所有情况,这个假发与自己的头发颜色相同。所以我查询WHERE contacts.HairColor = product.WigColor
。我是否应该在每个客户之间获得匹配,我不知道头发的颜色和没有WigColor
的产品?不,他们是另一回事。
让我们考虑NULL是 unknown 的另一个词。 ('Smith' = NULL)
的结果是什么?答案是 not false ,它是未知。未知不是真的,因此表现得像假。 (NULL = NULL)
的结果是什么?答案也是未知的,因此也是有效的错误。 (这也是为什么将字符串与NULL值连接使整个字符串变为NULL - 结果确实是 unknown 。)
答案 11 :(得分:0)
为什么不使用isnull功能?
@where = "where GroupId = "+ isnull(@groupId,"null")