SQL进价2:三值逻辑和null
1、SQL中的bool类型的值有三种
普通编程语言里的布尔型只有 true
和 false
两个值,这种逻辑体系被称为二值逻辑。而 SQL 语言里,除此之外还有第三个值 unknown
,因此这种逻辑体系被称为三值逻辑(three-valued logic)。
2、null不是值,与数学运算符结果的结果永远是unknown
常听到的“列的值为 NULL
” 、“NULL
值”这样的说法本身就是错误的。因为 NULL
不是值,NULL
不是值NULL
不是值!(如果有人认为 NULL
是值,那么它是什么类型的值?关系数据库中存在的值必然属于某种类型,比如字符型或数值型等。所以,假如 NULL
是值,那么它就必须属于某种类型。)
另外,注意:要想和null比较只能用 is null 或者 is not null,这样才会返回true或者false。另外永远记住一点,null和<,<,=,<>这些放在一起结果永远是unknown,如 2=null,结果肯定是unknown,而unknown可在三值逻辑中不是true或者false,在写where子句的筛选条件时尤其要注意。举例来讲:
接下来我们总结一下 SQL 遵循的三值逻辑的真值规律(理解下面这些非常重要)。
先看下图:(t:true,f:false,u:unknown。not unknown 的结果是 unknown)
我们经常会遇到判断筛选条件的结果(为true/false/unknown的一种,且SQL只会取返回结果是true的记录),它们通常是and 或or连接这些单个条件的,如:where age>18 and sex=0或where age<18 and sex =unknown。所以我们要牢牢记住上面这个图,才能对各种情况下返回的数据心里有底。
记忆方式1:
and运算,只要有一边是unknown,另一边是false,那结果就是false,其它情况下,只要任意一边有unknown,结果就是unknown。
or运算,只要一边是unknown,那么结果永远就是unknown
记忆方式2:
在判断and或or的最终结果时,请注意true/false/unknown之间有下面这样的优先级顺序。
AND
的情况:false
>unknown
>true
OR
的情况:true
>unknown
>false
优先级高的真值会决定计算结果。例如 true AND unknown
,因为 unknown
的优先级更高,所以结果是 unknown
。而 true OR unknown
的话,因为 true
优先级更高,所以结果是 true
。记住这个顺序后就能更方便地进行三值逻辑运算了。特别需要记住的是,当 AND
运算中包含 unknown
时,结果肯定不会是 true
(反之,如果 AND
运算结果为 true
,则参与运算的双方必须都为 true
)。这一点对理解后文非常关键。
3、NOT IN 和 NOT EXISTS 不是等价的
如果 NOT IN
子查询中用到的表里被选择的列中存在 NULL
,则 SQL 语句整体的查询结果永远是空。EXISTS
谓词永远不会返回 unknown
。EXISTS
只会返回 true
或者 false
。因此就有了 IN
和 EXISTS
可以互相替换使用,而 NOT IN
和 NOT EXISTS
却不可以互相替换的混乱现象。
4、ALL
运算符与null
以下是ALL
运算符语法:
scalar_expression comparison_operator ALL ( subquery )
在上面语法中,
scalar_expression
是任何有效的表达式。comparison_operator
是任何有效的比较运算符,包括等于(=
),不等于(<>
),大于(>
),大于或等于(>=
),小于(<
),小于或等于(<=
)。- 括号内的子查询(
subquery
)是一个SELECT语句,它返回单个列的结果。 此外,返回列的数据类型必须与标量表达式的数据类型相同。
如果所有比较对(scalar_expression,v)
的计算结果为TRUE
,则ALL
运算符返回TRUE
; v
是单列结果中的值。
如果其中一对(scalar_expression,v)
返回FALSE
,则ALL
运算符返回FALSE
。
如果all里面的子查询返回的单列中有null的存在,那么这个all表达式就永远不会筛选出任何数据,结果肯定为空。
因为ALL
谓词其实是多个以 AND
连接的逻辑表达式的省略写法。
如果all里面的子查询返回的单列中有null的存在,比如子查询结果如下面这个情况,那么具体的分析步骤如下所示。
--1. 执行子查询获取年龄列表
SELECT *
FROM Class_A
WHERE age < ALL ( 22, 23, NULL );
--2. 将ALL 谓词等价改写为AND
SELECT *
FROM Class_A
WHERE (age < 22) AND (age < 23) AND (age < NULL);
--3. 对NULL 使用“<”后,结果变为 unknown
SELECT *
FROM Class_A
WHERE (age < 22) AND (age < 23) AND unknown;
--4. 如果AND 运算里包含unknown,则结果不为true
SELECT *
FROM Class_A
WHERE false 或 unknown;
--5.查询结果为空
SQL进价2:三值逻辑和null的更多相关文章
- SQL Server 排序的时候使 null 值排在最后
https://www.cnblogs.com/Brambling/p/7046148.html 最近遇到一个 SQL Server 排序的问题,以前也没了解过,然后这次碰到了. 才发现 SQL Se ...
- SQL Server、Oracle和MySQL中查出值为NULL的替换
参考文献: http://database.51cto.com/art/200803/67397.htm 正文 在SQL Server Oracle MySQL当数据库中查出某值为NULL怎么办? 1 ...
- SQL Server排序的时候使null值排在最后
首先建一个表插入一些测试数据 create table UserInfo ( UserInfoID int not null identity(1,1) primary key, Use ...
- SQL - where条件里的!=会过滤值为null的数据
!=会过滤值为null的数据 在测试数据时忽然发现,使用如下的SQL是无法查询到对应column为null的数据的: select * from test where name != 'Lewis'; ...
- mybatis查询出字段为null,但是sql查出来有值
mybati 查出字段值为null, 然而相同的sql查出字段确实有值 原因: 在接受对象中使用了继承 :也就是说继承类与父类都定义了这个属性 ,字段重复,删除子类属性即可
- 你真的会玩SQL吗?三范式、数据完整性
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- SQL总结(三)其他查询
SQL总结(三)其他查询 其他常用的SQL,在这里集合. 1.SELECT INTO 从一个表中选取数据,然后把数据插入另一个表中.常用于创建表的备份或者用于对记录进行存档. 语法: SELECT c ...
- sql 列设置默认值,语法查询知识点积累
一.修改字段默认值 alter table 表名 drop constraint 约束名字 ------说明:删除表的字段的原有约束 alter table 表名 add constraint 约 ...
- SQL学习笔记三(补充-2)之MySQL数据类型
阅读目录 一 介绍 二 数值类型 三 日期类型 四 字符串类型 五 枚举类型与集合类型 一 介绍 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 ...
随机推荐
- mvc手把手教你写excel导入[mvc+三层,没用EF]
实习狗的每天新知识日常 准备工作: 1.在项目中添加对NPOI的引用,NPOI下载地址:http://npoi.codeplex.com/releases/view/38113 2.NPOI学习系列教 ...
- 文本框改变之onpropertychange事件
onpropertychange能够捕获每次输入值的变化. 例如:对象的value值被改变时,onpropertychange能够捕获每次改变,而onchange需要执行某个事件才可以捕获. 在文本框 ...
- C#三大特性之 封装、继承、多态
一.封装: 封装是实现面向对象程序设计的第一步,封装就是将数据或函数等集合在一个个的单元中(我们称之为类).被封装的对象通常被称为抽象数据类型. 封装的意义: 封装的意义在于保护或者防止代码(数据) ...
- 撩课-Web大前端每天5道面试题-Day7
1. 你能描述一下渐进增强和优雅降级之间的不同吗? 定义: 优雅降级(graceful degradation): 一开始就构建站点的完整功能, 然后针对浏览器测试和修复 渐进增强(progressi ...
- delphi之读写文件的三种方式
一.Tstrings.Tstringlist procedure TForm1.Button2Click(Sender: TObject); var strlist: TStringList; pat ...
- Spring入门(三)— AOP注解、jdbc模板、事务
一.AOP注解开发 导入jar包 aop联盟包. aspectJ实现包 . spring-aop-xxx.jar . spring-aspect-xxx.jar 导入约束 aop约束 托管扩展类和被扩 ...
- Java 社区论坛 - Sym 1.5.0 发布
简介 Sym 是一个用 Java 写的实时论坛,欢迎来 体验!(如果你需要搭建一个企业内网论坛,请使用 SymX) 非常详细的 Sym 功能点脑图 如果你在搭建或者二次开发时碰到问题,欢迎加 Q 群 ...
- System.Media.Color与System.Drawing.Color转换方法
public static System.Media.Color GetMediaColorFromDrawingColor(System.Drawing.Color color) { re ...
- Android 图片旋转
拍照后的照片有时被系统旋转,纠正步骤如下: 1.先读取图片文件被旋转的角度: /** * 通过ExifInterface类读取图片文件的被旋转角度 * @param path : 图片文件的路径 * ...
- 使用拦截器拦截html参数
公司最新需求:根据传递的参数进行业务判断,如果符合条件则继续后面的业务逻辑,否则跳转到指定的错误页面.有些是请求的controller 使用了spring aop的方式进行验证:但是有些是html页 ...