SQL中的三值逻辑

三值逻辑指的是SQL总的Boolean类型有三个真值,分别是truefalseunknow。当值缺失时会使用NULL这个标识符来标识,而对NULL使用比较谓词时其结果永远是unknow,例如1 = null 返回unknow,1 > null 返回unknow,null = null也返回unknow。
三值优先级:
在AND中 FALSE > unknow > TRUE
在OR中 TRUE > unknow > FALSE

WHERE子句只会筛出返回为TRUE的记录

在SQL中NULL并不是一个值,而是一个标识符,表示该值不知道。而谓词表达式只能作用于值,当谓词表达式作用于NULL标识符时取代报错的是返回unknow这个布尔值。
因为NULL不是值所以不能用谓词来判断是否为NULL,只能通过IS NULL来判断该值是否为NULL,更加让人混淆的是IS TRUE也是合法的,确实有点尴尬。
所以说来说去在语法上并没有直接证据表明在SQL中NULL是一个特殊存在,它不是值。

三值逻辑带来的影响

直接影响是排中律不成立

把命题和它的否命题通过‘或者’连接而成的命题全都是真命题”这个命题在二值逻辑中被称为排中律(law of excluded middle)

这个人是20岁或者不是20岁在三值逻辑下不成立,因为还有一种可能是不知道。

-- 查询年龄是 20 岁或者不是 20 岁的学生
SELECT *
  FROM Students
WHERE age = 20 OR age <> 20;

若想筛出全部,需要做如下修改。

-- 查询年龄是 20 岁或者不是 20 岁的学生
SELECT *
  FROM Students
WHERE age = 20 OR age <> 20 OR age IS NULL;

CASE表达式和NULL

CASE表达式和WHERE子句一样,只会返回TRUE的结果,所以unknow的引入也会对CASE表达式造成影响。

CASE WHEN col_1 = 1     THEN '○'
     WHEN col_1 IS NULL THEN '×'
END

如上例,col_1如果是NULL则只能通过col_1 IS NULL来判断。

NOT IN 和 NOT EXISTS不等价

age NOT IN (22, 23, NULL);

转换为

age != 22 AND age != 23 AND age != NULL -- 返回unknow

NOT IN的入参集合里面如果有NULL,那么即使age等于22也无法筛出该条记录。而IN则不会有这个问题,因为IN的拆解是OR,在ORTRUE的优先级高于unknow

而NOT EXISTS的返回会过滤掉NULL值

NOT EXISTS (SELECT * from Students WHERE age != 22 AND age != 23 AND age != NULL);

和没有值进行运算得到的unknow,也可以表示"不知道UNKNOW"和"不适用not applicable, inapplicable"这两种,例如:
戴墨镜的人眼睛是什么颜色?不知道表示的是满足某种条件时可以知道
冰箱的眼睛是什么颜色?不知道表示的是不适用,因为冰箱没有眼睛,无论满足什么条件都无法知道,这个问题没有意义

除了WHERE和CASE会自动过滤掉unknow的数据,在SELECT子句中使用的函数例如,COUNT、MAX等函数也会自动过滤掉NULL。

参考

SQL 进阶教程 (第2版)[日]MICK - 人民邮电出版社

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值