例如:对于有头发这个属性,对象为冰箱时就是不适合,因为冰箱不可能存在头发这个属性。当对象为人时,这个属性存在,当摘下帽子就可知道了。
因为对null比较时使用谓词(= > < !=等)返回的结果是unknown,而使用where筛选出来的都是判断结果为true的行,所以使用“=null”无法显示出包含null的行。
对null比较时使用谓词得到结果不能为真是因为,null既不是值也不是变量,而比较谓词只适用于值。
sql三值逻辑中的三种值:true,false,unknown
三值逻辑的真值表
x | NOT x |
---|---|
t | f |
u | u |
f | t |
AND | t | u | f |
---|---|---|---|
t | t | u | f |
u | u | u | f |
f | f | f | f |
false >?unknown >?true
OR | t | u | f |
---|---|---|---|
t | t | t | t |
u | t | u | u |
f | t | u | f |
true >?unknown >?false
SELECT *
FROM Students
WHERE age = 20
OR age <> 20
OR age IS NULL;
CASE col_1
WHEN 1 THEN ‘○‘
WHEN NULL THEN ‘ב
END
一定不会返回null,因为WHEN NULL相当于col_1 = NULL 的缩写形式,真值永远为unknown。以下为正确的写法
CASE WHEN col_1 = 1 THEN ‘○‘
WHEN col_1 IS NULL THEN ‘ב END
SELECT *
FROM Class_A
WHERE age NOT IN
( SELECT age
FROM Class_B
WHERE city = ‘东京‘ );
过程详解:
--1. 执行子查询,获取年龄列表
SELECT *
FROM Class_A
WHERE age NOT IN (22, 23, NULL);
--2. 用 NOT 和 IN 等价改写 NOT IN
SELECT * FROM Class_A
WHERE NOT age IN (22, 23, NULL);
--3. 用 OR 等价改写谓词 IN
SELECT *
FROM Class_A
WHERE NOT ( (age = 22) OR (age = 23) OR (age = NULL) );
--4. 使用德·摩根定律等价改写
SELECT *
FROM Class_A
WHERE NOT (age = 22) AND NOT(age = 23) AND NOT (age = NULL);
--5. 用 <> 等价改写 NOT 和 =
SELECT *
FROM Class_A
WHERE (age <> 22) AND (age <> 23) AND (age <> NULL);
--6. 对 NULL 使用 <> 后,结果为 unknown
SELECT *
FROM Class_A
WHERE (age <> 22) AND (age <> 23) AND unknown;
--7.如果 AND 运算里包含 unknown,则结果不为 true
SELECT *
FROM Class_A
WHERE false 或 unknown;
如果 NOT IN 子查询 中用到的表里被选择的列中存在 NULL,则 SQL 语句整体的查询结果永远 是空
SELECT *
FROM Class_A A
WHERE NOT EXISTS
( SELECT *
FROM Class_B B
WHERE A.age = B.age
AND B.city = ‘东京‘ );
过程详解:
--1. 在子查询里和 NULL 进行比较运算
SELECT *
FROM Class_A A
WHERE NOT EXISTS
( SELECT *
ROM Class_B B
WHERE A.age = NULL
AND B.city = ‘东京‘ );
--2. 对 NULL 使用“=”后,结果为 unknown
SELECT *
FROM Class_A A
WHERE NOT EXISTS
( SELECT *
FROM Class_B B
WHERE unknown
AND B.city = ‘东京‘ );
--3. 如果 AND 运算里包含 unknown,结果不会是 true
SELECT *
FROM Class_A A
WHERE NOT EXISTS
( SELECT *
FROM Class_B B
WHERE false 或 unknown);
--4. 子查询没有返回结果,因此相反地,NOT EXISTS 为 true
SELECT *
FROM Class_A A
WHERE true;
-- 查询比 B 班住在东京的所有学生年龄都小的 A 班学生
SELECT *
FROM Class_A
WHERE age < ALL
( SELECT age
FROM Class_B
WHERE city = ‘东京‘ );
当B中有人年龄不详时查询结果为空。因为ALL 谓词其实是多个以 AND 连接的逻辑表达式的省略写法。所以子查询中有null时where后的值不为true。
6.聚合函数和 NULL
当子查询输入为空表时返回null不仅有极值函数,还有count等聚合函数,所以外侧查询也返回不了任何值。
注:参考文献 sql进阶教程
原文:https://www.cnblogs.com/DA-fighting/p/12680231.html