1-3 三值逻辑和null-SQL进阶教程

二值逻辑
布尔型只有true和false两个值

三值逻辑
布尔型除true和false之外还有第三个值unknown

null既不是值也不是变量,null只是一个表示“没有值”的标记
因为null不是值,所以不能对其使用谓词
对null使用谓词后的结果是unknown

1. 比较谓词和null(1):排中律不成立

排中律
把命题和它的否命题通过‘or’连接而成的命题全都是真命题
由于存在null值,在SQL的世界里,排中律是不成立的

在这里插入图片描述

-- 添加第3个条件:年龄是20岁,或者不是20岁,或者年龄未知
select *
from Students
where age=20
or age<>20
or age is null;

2. 比较谓词和null(2) :CASE表达式和null

-- 错误写法
case col_1
when 1 then '○'
when null then '×' -- 这里的when子句是col_1=null的缩写形式
end;

-- 正确写法
case 
when col_1=1 then '○'
when col_1 is null then '×'
end;

3. not in和not exists不是等价的

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

-- 查询与B班住在东京的学生年龄不同的A班学生
select *
from Class_A
where age not in(
	select age
	from Class_B
	where city = '东京'
);
/*
如果not in子查询中用到的表里被选择的列中存在null,则SQL语句整体的查询结果永远是空
*/

-- 正确的SQL语句:拉里和伯杰将被查询到
select *
from Class_A A
where not exists(
	select *
	from Class_B B
	where A.age=B.age
	and B.city='东京'
);
/*
exists谓词永远不会返回unknown。exists只会返回true或者false
因此in和exists可以互相替换使用,而not in和not exists却不可以互相替换
*/

4. 限定谓词和null

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

-- 查询比B班住在东京的所有学生年龄都小的A班学生
select *
from Class_A
where age<all(
	select age
	from Class_B
	where city='东京'
);
/*
如果山田年龄不详,这条SQL语句的执行结果将为空
因为all谓词其实是多个以and连接的逻辑表达式的省略写法
*/

5. 限定谓词和极值函数不是等价的

select *
from Class_A
where age<(
	select min(age)
	from Class_B
	where city='东京'
);
/*
即使山田的年龄无法确定,这段代码也能查询到拉里和伯杰两人
因为,极值函数在统计时会把为null的数据排除掉
*/

限定谓词≠极值函数:
①表里存在null时
②谓词(或者函数)的输入为空集

比较对象原本就不存在时,根据业务需求有时需要返回所有行,有时需要返回空集
需要返回所有行时,需要使用all谓词,或者使用coalease函数将极值函数返回的null处理成合适的值

6. 聚合函数和null

当输入为空表时返回null的不只是极值函数,count以外的聚合函数也是如此

-- 查询比住在东京的学生的平均年龄还要小的A班学生
select * 
from Class_A
where age<(
	select avg(age)
	from Class_B
	where city='东京'
);
/*
没有住在东京的学生时,avg函数返回null
这种情况的解决方法只有两种:要么把null改写成具体值,要么闭上眼睛接受null
但是如果某列有not null约束,而我们需要往其中插入平均值或汇总值,那么就只能选择将 null改写成具体值了

聚合函数和极值函数的这个陷阱是由函数自身带来的,所以仅靠为具体列加上not null约束是无法从根本上消除的
*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值