SQL进阶之三值逻辑与NULL

三值逻辑与NULL

越前须知(雾)

  • 本系列参考《SQL进阶教程》1,DBMS选用MySQL。
  • 本系列不涉及数据库安装与基础语句,对初学者存在一定门槛;基础知识建议阅读《SQL必知必会(第四版)》与《SQL基础教程(第二版)》。

三值逻辑概述

  1. 普通语言里的布尔型只有 true 和 false 两个值,即二值逻辑;SQL中有 true、false 和 unknown,即三值逻辑;
  2. 关系模型并不是描述现实世界的模型,而是描述人类认知状态的核心(知识)的模型,我们有限且不完备的知识也会直接反映在表里;
  3. 三值逻辑优先顺序:
  • AND: False > Unknown > True;若AND运算真值为 True,即参与运算的字段条件均为 True
  • OR:True > Unknown > False;

具体应用

简单规则

Q:为什么WHERE co l_1 = NULL 会出错?
A:NULL不是值,只是一个“没有值”的标记,需要用 where col_1 is null

select * from tbl_A where col_1 = null;  -- 结果为空

select * from tbl_A where col_A is null;

Q:排中律在SQL中是否成立?(排中律:一个人年龄要么等于20,要么不等于20)
A:在SQL中,排中律不存在

select * 
	from Students 
	where age = 20 
	or age <> 20;     -- 无法查询出年龄为NULL的学生

Q:CASE表达式中,NULL应该怎么写?
A:搜索表达式 + IS NULL

case col_1
	when 1 then '〇'
	when null then 'x'   -- 表达式为 col_1 = NULL,结果为空
end;   

case when col_1 = 1 then '〇'
	 when col_1 is null then 'x'
end;

NOT IN 和 NOT EXISTS 不等价

  • 创表
CREATE TABLE Class_A
(name VARCHAR(16) PRIMARY KEY,
 age  INTEGER,
 city VARCHAR(16) NOT NULL );

CREATE TABLE Class_B
(name VARCHAR(16) PRIMARY KEY,
 age  INTEGER,
 city VARCHAR(16) NOT NULL );

INSERT INTO Class_A VALUES('布朗',   22, '东京');
INSERT INTO Class_A VALUES('拉里',   19, '埼玉');
INSERT INTO Class_A VALUES('伯杰',   21, '千叶');

INSERT INTO Class_B VALUES('齐藤',  22,   '东京');
INSERT INTO Class_B VALUES('田尻',  23,   '东京');
INSERT INTO Class_B VALUES('山田',  NULL, '东京');
INSERT INTO Class_B VALUES('和泉',  18,   '千叶');
INSERT INTO Class_B VALUES('武田',  20,   '千叶');
INSERT INTO Class_B VALUES('石川',  19,   '神奈川');

Q:查询“与B班住在东京的学生年龄不同的A班学生”,即“拉里”和“伯杰”
A:不能用NOT IN

  • NOT IN:在子查询存在NULL时,查询结果永远为空
  • NOT EXISTS:不受子查询中NULL影响
-- NOT IN:结果为空
select * 
	from Class_A 
	where age not in (select age 
	                      from Class_B as B 
                      	  where B.city = '东京');
                      		
-- NOT EXISTS:不受NULL影响
select * 
	from Class_A as A 
	where not exists (select * 
                      	from Class_B as B 
                      	where A.age = B.age 
                    	and B.city = '东京');

限定谓语 (ALL、ANY) 和NULL

Q:ANY相当与IN;ALL和比较谓语联用表示“与所有的XX都相等”、“比所有的XX都大”,若遇到NULL
A:若ANY、ALL遇到NULL,查询结果永远为空

select * 
	from Class_A as A 
	where age < all (select age 
                         from Class_B as B 
                     	 where B.city = '东京');

极值函数 (MAX、MIN) 和NULL

Q:MAX和比较谓语联用表示“比XXX里最大的更大”,若遇到NULL
A:极值函数只对非NULL起作用

  • 若少量值为NULL,则MAX表示“比XXX剩下非NULL里最大的更大”;
  • 若整个子查询为NULL,则查询结果为空
select * 
	from Class_A as A 
	where age < (select min(age) 
                  	 from Class_B 
                     where city = '东京');

聚集函数 (COUNT、AVG) 和NULL

  • 除了COUNT(*),其他聚集函数与极值函数一样,只对非NULL起作用

  1. MICK[日] 《SQL进阶教程》 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值