在大多数SQL实现中,与标准编程语言相反,为什么x!= null不返回true?

时间:2012-06-21 20:08:39

标签: sql null

假设x是一个除null之外的任何值的变量,例如4,作为示例。下面的表达式应该返回什么?

x != null

在我曾经使用的几乎所有编程语言(C#,Javascript,PHP,Python)中,此表达式或该语言中的等效表达式的计算结果为true

另一方面,SQL实现似乎完全不同地处理这个问题。如果不等式运算符的一个或两个操作数为NULL,则将返回NULLFalse。这基本上与大多数编程语言使用的行为相反,而且非常对我不直观。

为什么SQL中的行为是这样的?什么是关系数据库逻辑,使null的行为与通用编程中的行为有很大不同?

4 个答案:

答案 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关键字。

如果您只想将空值视为零或其他值,则可以使用COALESCEISNULL函数。

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.