6

让我们假设这x是一个具有除 之外的任何值的变量null,例如 4。下面的表达式应该返回什么?

x != null

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

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

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

4

4 回答 4

7

大多数编程语言中的 null 被认为是“已知的”,而 SQL 中的 NULL 被认为是“未知的”。

  • 因此X == null将 X 与已知值进行比较,结果是已知的(真或假)。
  • 但是X = NULL将 X 与未知值进行比较,结果未知(即再次为 NULL)。因此,我们需要一个特殊的运算符IS [NOT] NULL来测试它。

我猜测这种 NULL 的至少部分动机是外键的行为。当外键的子端点为 NULL 时,它不应该匹配任何父节点,即使父节点为 NULL(如果父节点是 UNIQUE 而不是主键,这是可能的)。不幸的是,这带来了它解决的问题更多的问题,我个人认为 SQL 应该走“已知”空值的路线,并完全避免这种猴子业务。

即使是 EF Codd,发明者或关系模型,后来也表示传统的 NULL 不是最优的。但由于历史原因,我们几乎坚持下去。

于 2012-06-21T20:43:51.100 回答
6

原因是相等的概念不适用于 null。说这个空值等于或不等于另一个空值在逻辑上是不正确的。

所以,从理论上讲这一切都很好,但是为了方便起见,为什么 sql 不允许你说 (x != null)?

好吧,原因是有时您想以不同的方式处理空值。例如,如果我说 (columnA = columnB),如果两列都为空,是否应该返回 true?如果我说 (columnA != columnB) - 当 A 列为“a”且 B 列为空时,以及 A 列为“a”且 B 列为“b”时,它是否应该给出相同的结果?

制作 sql 的人认为区分很重要,因此他们编写它以区别对待这两种情况。

维基百科页面上有一个相当不错的文章 - http://en.wikipedia.org/wiki/Null_%28SQL%29

于 2012-06-21T20:22:35.573 回答
1

在 sql 引擎中,您通常不使用“=”运算符,而是使用“IS”,这使其更直观。

SELECT 4 IS NULL FROM dual;
> 0


SELECT 4 IS NOT NULL FROM dual;
> 1

NULL 不代表空指针,它根本不是同一个概念。sql NULL 是一个我不知道值标志,它不是一个“没有指针”标志。您只是不应该比较它们,它们不应该以相同的方式使用。这很不直观,你是对的,他们应该以不同的方式命名它。

于 2012-06-21T20:15:05.180 回答
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

检查空值的唯一方法是特别询问“我们是否真的不知道 x 的值是什么”。那有一个是或否的答案,并使用IS关键字。

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

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.
于 2012-06-21T20:45:39.347 回答