本文整理自网络,侵删。
目录
- 1. 前言
- 2. 两种 Null
- 3. 为什么是 is Null 而不是 = Null ?
- 4. 第三个真值 “unknown”
- 5. 包含三值逻辑的真值表
- 6. “排中律” 不再成立
- 7. CASE 表达式和 NULL
- 8. NOT IN 和 NOT EXISTS 不是等价的
- 9. 限定谓词和 NULL
- 10. 限定谓词和极值函数不是等价的
- 11. 聚合函数和 Null
1. 前言
大多数编程语言都是基于二值逻辑的,即逻辑真值只有真和假两个。而 SQL 语言则采用一种特别的逻辑体系——三值逻辑,即逻辑真值除了真和假,而 SQL 语言里,除此之外还有第三个值 unknown
,因此这种逻辑体系被称为三值逻辑(three-valued-logic)。
2. 两种 Null
- 表示未知 (unknown):“不知道戴墨镜的人眼睛是什么颜色”这种情况为例,这个人的眼睛肯定是有颜色的,但是如果他不摘掉眼镜,别人就不知道他的眼睛是什么颜色。这就叫作未知。
- 表示不适用 (not applicable 或 inapplicable):“不知道冰箱的眼睛是什么颜色”则属于“不适用”。因为冰箱根本就没有眼睛,所以“眼睛的颜色”这一属性并不适用于冰箱。
“冰箱的眼睛的颜色”这种说法和“圆的体积”“男性的分娩次数”一样,都是没有意义的。平时,我们习惯了说“不知道”,但是“不知道”也分很多种。“不适用”这种情况下的 NULL ,在语义上更接近于“无意义”,而不是“不确定”。
总结:“未知”指的是“虽然现在不知道,但加上某些条件后就可以知道”;而“不适用”指的是“没有办法知道”。
3. 为什么是 is Null 而不是 = Null ?
“我们先从定义一个表示‘虽然丢失了,但却适用的值’的标记开始。我们把它叫作 A-Mark。这个标记在关系数据库里既不被当作值(value),也不被当作变量 (variable)。”(E.F. Codd,The Relational Model for Database Management :Version 2 , P.173) “关于 NULL 的很重要的一件事情是,NULL 并不是值。”(C.J. Date, An Intruction To Database System (6th edition ), P.619)
对 NULL 使用比较谓词后得到的结果总是 unknown 。而查询结果只会包含 WHERE 子句里的判断结果为 true 的行,不会包含判断结果为 false 和 unknown 的行。不只是等号,对 NULL 使用其他比较谓词,结果也都是一样的。
-- 以下的式子都会被判为 unknown 1 = NULL 2 > NULL 3 < NULL 4 <> NULL NULL = NULL
那么,为什么对 NULL 使用比较谓词后得到的结果永远不可能为真呢?这是因为,NULL 既不是值也不是变量。NULL 只是一个表示“没有值”的标记,而比较谓词只适用于值。因此,对并非值的 NULL 使用比较谓词本来就是没有意义的。(Null只是一个作为区分的标记,并不是一个值)
“列的值为 NULL ”“NULL 值”这样的说法本身就是错误的。因为 NULL 不是值,所以不在定义域(domain)中。相反,如果有人认为 NULL 是值,那么请区分一下:它是什么类型的值?关系数据库中存在的值必然属于某种类型,比如字符型或数值型等。所以,假如 NULL 是值,那么它就必须属于某种类型。( SQL 里的 NULL 和其他编程语言里的 NULL 是完全不同的东西)
4. 第三个真值 “unknown”
因关系数据库采用了 NULL 而被引入了 “第三个真值”。这里有一点需要注意:真值 unknown 和作为 NULL 的一种的 UNKNOWN (未知)是不同的东西。前者是明确的布尔型的真值,后者既不是值也不是变量。(下文使用 unknown 表示 真值,UNKNOWN 表示 代表Null的一个 标记)
举个栗子: unknown = unknown
判定为 true
而 UNKNOWN = UNKNOWN
( 也就是 Null = Null
) 判定为 unknown
5. 包含三值逻辑的真值表
当两个值进行逻辑判断的时候的优先级,优先级高的真值会决定计算结果:
- AND 的情况: false > unknown > true
- OR 的情况: true > unknown > false
举个栗子: true AND unknown ,因为 unknown 的优先级更高,所以结果是 unknown 。而 true OR unknown 的话,因为 true 优先级更高,所以结果是 true 。
6. “排中律” 不再成立
“把命题和它的否命题通过‘或者’连接而成的命题全都是真命题” 这个命题在二值逻辑中被称为排中律(Law of Excluded Middle)。顾名思义,排中律就是指不认可中间状态,对命题真伪的判定黑白分明,是古典逻辑学的重要原理。
举个栗子:现实生活中 一个学生 是20岁 或者 不是20岁,不会有第三种情况。
但是在SQL中并不是这个样:
-- 查询年龄是20 岁或者不是20 岁的学生 SELECT * FROM Students WHERE age = 20 OR age <> 20;
在现实生活中,上面的查询条件应该包含所有的学生,但是这里的执行结果并不会查询到约翰。
--- 当查询到约翰哪一行时的判定 WHERE Null = 20 OR Null <> 20 --- 根据上文的描述,该条件会转换为 WHERE unknown OR unknown 等同于 WHERE unknown
若要查到所有学生需要再加上一个条件:OR age IS NULL
7. CASE 表达式和 NULL
CASE col_1 WHEN 1 THEN '○' WHEN NULL THEN '×' END
上面的这个CASE表达式会在 col_1 为 1 时返回 ○
、为 NULL 时返回 ×
吗?显然始终不会返回 x
因为第二个 WHEN 子句是 col_1 = NULL 的缩写形式,根据上文的描述 col_1 = NULL 始终会返回 unknown 而 CASE 表达式的判断方法与 WHERE 子句一样,只认可真值为 true 的条件,所以 x
并不会出现。下面才是正确的写法:
CASE WHEN col_1 = 1 THEN '○' WHEN col_1 IS NULL THEN '×' END
8. NOT IN 和 NOT EXISTS 不是等价的
在对 SQL 语句进行性能优化时,经常用到的一个技巧是将 IN 改写成EXISTS 。这是等价改写,并没有什么问题。问题在于,将 NOT IN 改写成 NOT EXISTS 时,结果未必一样。
相关阅读 >>
mysql和sql是什么?mysql和sql之间的区别有哪些
区分mysql中的空值(null)和空字符('')
更多相关阅读请进入《sql》频道 >>

数据库系统概念 第6版
机械工业出版社
本书主要讲述了数据模型、基于对象的数据库和XML、数据存储和查询、事务管理、体系结构等方面的内容。
转载请注明出处:木庄网络博客 » 一文详解SQL中的三值逻辑
相关推荐
评论
管理员已关闭评论功能...