为什么is null 是模糊查询?| 一文讲懂SQL NULL

为什么is null 是模糊查询?| 一文讲懂SQL NULL

https://zhuanlan.zhihu.com/p/82434024 直接转载这篇文章,里面的相亲例子让人很好理解

很多人会将NULL称为“空值”。但这个称呼是非常有迷惑性的。事实上,SQL中的NULL不仅不是“空值”,NULL甚至不能被视作一个“值”。那么,你到底对SQL中的NULL了解多少呢?

此 NULL 非彼 NULL

首先,NULL 不等于0,也不是’'(空字符串)。 这很好理解。

其次,NULL 也不是空值。空值,亦是一种值,表示此处确定为空。而 NULL 是一个更未知的状态——可能有值,可能无值,可能存在,可能不存在,可能是任何值,可能不是任何值。总之一切皆有可能。

这一点和许多编程语言都不相同,不少语言中的 NULL,就是空值的意思。例如,在 C、C++ 等语言中,NULL 表示空指针,是一个计算机保留的值,表示不引用有效对象。但是 SQL 中的 NULL 用法和它们并不一样。

最后,NULL 甚至都不是一种值。它不是“无值”,也不是“未知值”,它只是一个标记符号。此处的值不确定,所以用 NULL 作为占位符来标记一下而已。NULL 不是值,NULL 的值不确定,因此 NULL 与 NULL 是不相同的。在逻辑判断中,NULL=NULL 返回的判断结果不是 TRUE ,而是 NULL。因为,未知和未知是无法进行比较的。

想要理解这一点也不难——假设你有两场相亲。在见面之前,你对这两个相亲对象的具体信息一无所知。因此,这俩人对你来说,都是“未知的”,都可以标记为 NULL。但是,你能说这俩人是同一个人吗?不能吧。但是,你能说这俩一定不是同一个人吗?也不一定吧。

NULL 的传递

在 SQL 中,NULL 这个“未知”的状态,是可传递的。譬如,对 NULL 进行算术运算,结果都是NULL。

-- Result is NULL
SELECT 2 + NULL;
SELECT 2 - NULL;
SELECT 2 * NULL;
SELECT 2 / NULL;

值得注意的是,用 NULL 除以 0 时,许多数据库系统并不会返回"data exception — division by zero"的错误,而是返回 NULL。例如,MySQL、Oracle、PostgreSQL等等。

-- Result is NULL
SELECT NULL / 0;

此外,NULL 还可以运用于字符串的连接中。将 NULL 和其他字符串相连接,其结果也是 NULL。

三值逻辑

理解了 NULL 并非一个值,而是一个符号,才能更好地理解 SQL 中的逻辑判断关系。也许有人不解,NULL是一个值也好,是一个符号也好,有什么区别吗?不都是用来表达“不确定”、“未知”的意思吗?

这区别,可大了去了~。前面我们提到,当将两个 NULL 进行比较时,得到的逻辑运算结果不是 TRUE 而是 NULL 。那么,到底为什么会是这样呢?如果 NULL 值无法进行比较,那么该如何对 NULL 进行筛选和查询呢?

下面,介绍新名词,「三值逻辑」。

首先,我们先来复习一下二值逻辑。 传统的真假逻辑,就是二值逻辑。对于一个给定的命题,它要么为真,要么为假,非真即假,非假即真。在二值逻辑中,逻辑运算的结果只有真和假,不存在任何中间态。

今天下了雨。这句话要么为真,即真的下雨了;要么为假,即今天没下雨。

但是,世间的事情,哪里都是这么简单的非黑即白呢~。非真即假,非好即坏,是理想中的世界,而现实世界要复杂得多。对于一个命题,它不仅有可能是真的,有可能是假的,还有可能是咱不知道的、判断不了的。那么,现在就有真、假、未知,三种结果,即三值逻辑。

今天下雨了。这句话有三种可能性:(1)真,今天下雨了;(2)假,今天没下雨;(3)未知,我今天没出门,不知道今天下没下雨。

NULL ,就是这个表示「未知」的标记符。对于一个命题来说,如果它非真,不意味着它一定为假,因为它也有可能是NULL;如果它非假,也并意味着它一定成立,因为它也有可能是NULL。TRUE/FALSE/NULL,三种逻辑运算结果,形成了三值逻辑体系。

当 NULL 参与逻辑运算时,逻辑运算的结果会变得有些“反直觉”。但只要理解了 NULL 的本质,规律也并不难记住。让我们来逐个击破。

「=」

当对 TRUE 和 FALSE 使用 = 进行判断时,结果很好理解,相同则为真,不同则为佳。那么,涉及到 NULL 呢?

NULL 意味着未知,意味着可能是任何数、任何值。对于不确定的对象,无法使用 = 进行比较。(也无法用 >、<、!= 等符号进行比较)当 = 两边有 NULL 时,结果一律是 NULL。

img

「IS」

无法对 NULL 进行比较,这可比较麻烦。如果我们需要从数据库中筛选出含/不含 NULL 的数据,该怎么办呢?这个时候,IS 就派上用场了。

使用 IS NULL,可以判断某处的数据是否为 NULL ,而不会将二者进行逻辑比较。

img

MySQL 中,= NULL 和 IS NULL的执行效果截然不同。

SELECT * FROM table WHERE column1 = NULL;
-- 运行结果:未选定任何行数据。(返回 0 行,但不提示语法错误) 
SELECT * FROM table WHERE column1 IS NULL;
-- 运行结果:选出 column1 值为 NULL 的数据。

「NOT」

我们知道,非真即假,非假即真。那么,非 NULL 呢?未知的对立面依然是未知,因此 NULL 的反面也依然是 NULL。

注意区分 NOT NULL 和 IS NOT NULL。在 MySQL 中,在 WHERE 子句中使用 = NOT NULL 时会报错。(1064-error in your SQL syntax)

img

「OR」

或命题遵从「同假则假,一真则真,其余为 NULL」。见下图。

img

「AND」

且命题遵从「同真则真,一假则假,其余为 NULL」。见下图。

img

posted @ 2021-12-31 16:45  Oh,mydream!  阅读(273)  评论(0编辑  收藏  举报