假设x
是一个除null
之外的任何值的变量,例如4,作为示例。下面的表达式应该返回什么?
x != null
在我曾经使用的几乎所有编程语言(C#,Javascript,PHP,Python)中,此表达式或该语言中的等效表达式的计算结果为true
。
NULL
,则将返回NULL
或False
。这基本上与大多数编程语言使用的行为相反,而且非常对我不直观。
为什么SQL中的行为是这样的?什么是关系数据库逻辑,使null
的行为与通用编程中的行为有很大不同?
答案 0 :(得分:7)
大多数编程语言中的null被认为是“已知”,而SQL中的NULL被认为是“未知”。
X == null
将X与已知值进行比较,结果已知(真或假)。X = NULL
将X与未知值进行比较,结果未知(即再次为NULL)。因此,我们需要一个特殊的运算符IS [NOT] NULL
来测试它。我猜这种NULL的动机至少部分是外键的行为。当外键的子端点为NULL时,它不应与任何父项匹配,即使父项为NULL(如果父项是UNIQUE而不是主键,则可能)。不幸的是,这带来了比它解决的更多gotchas,我个人认为SQL应该已经走了“已知”null的路线并且完全避免了这种猴子业务。
甚至E. F. Codd,发明者或关系模型,后来表明传统的NULL不是最优的。但由于历史原因,我们几乎坚持下去。
答案 1 :(得分:6)
原因是相等的概念不适用于null。说这个null与其他null相等或不相等,这在逻辑上是不正确的。
所以,从理论上讲,这一切都很好,但为了方便起见,为什么sql不允许你说(x!= null)?
嗯,原因是因为有时你想要以不同的方式处理空值。 如果我说(columnA = columnB)例如,如果两列都为空,那么它应该返回true吗? 如果我说(columnA!= columnB) - 如果列A是“a”而列B是空的,当列A是“a”而列B是“b”时,它是否应该给出相同的结果?
制作sql的人认为区别很重要,所以他们写这篇文章是为了区别对待2个案例。维基百科页面上有一篇相当不错的文章 - http://en.wikipedia.org/wiki/Null_%28SQL%29
答案 2 :(得分:1)
在sql引擎中你通常不使用“=”运算符而是使用“IS”,这样可以使它更直观。
SELECT 4 IS NULL FROM dual;
> 0
SELECT 4 IS NOT NULL FROM dual;
> 1
NULL不代表空指针,它根本就不是同一个概念。 sql NULL是我不知道值标志,它不是“没有指针”标志。你不应该比较它们,它们不应该以相同的方式使用。这是非常不直观的你是对的,他们应该以不同的方式命名。
答案 3 :(得分:0)
在SQL中,NULL
表示“未知值”。
如果你说x!= NULL你说“是x的值不等于未知值”。好吧,既然我们不知道什么是未知值,我们不知道x是否等于它。所以答案是“我不知道”。
类似地:
x = NULL OR 1=2 -- Unknown. 1=2 is not true, but we don't know about x=NULL
x = NULL OR 1=1 -- True. We know that at least 1=1 is true, so the OR is fulfulled regardless.
x = NULL AND 1=1 -- Unknown. We want them both to be true to fulful the AND
x = NULL AND 1=2 -- False. We know 1=2 is false, so the AND is not fulfilled regardless.
另外
-- Neither statement will select rows where x is null
select x from T where x = 1
select x from T where x != 1
检查null的唯一方法是具体问“我们不知道x的值是什么”。这有一个是或否答案,并使用IS
关键字。
如果您只想将空值视为零或其他值,则可以使用COALESCE
或ISNULL
函数。
COALESCE(NULL, 1) -- 1
COALESCE(NULL, NULL, 1) -- Also 1
COALESCE(x, y, z, 0) -- x, unless it is null, then y, unless it is null, then z, unless it is null in which case 0.