欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SQL进阶之三值逻辑与NULL

程序员文章站 2024-01-17 13:34:40
SQL进阶之三值逻辑与NULL三值逻辑与NULL越前须知(雾)三值逻辑概述具体应用简单规则NOT IN 和 NOT EXISTS 不等价限定谓语 (ALL、ANY) 和NULL极值函数 (MAX、MIN) 和NULL聚集函数 (COUNT、AVG) 和NULL三值逻辑与NULL越前须知(雾)本系列参考《SQL进阶教程》1,DBMS选用MySQL。本系列不涉及数据库安装与基础语句,对初学者存在一定门槛;基础知识建议阅读《SQL必知必会(第四版)》与《SQL基础教程(第二版)》。三值逻辑概述普...

三值逻辑与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进阶教程》 ↩︎

本文地址:https://blog.csdn.net/m0_46132995/article/details/108976994