我是靠谱客的博主 糟糕皮卡丘,最近开发中收集的这篇文章主要介绍SQL查询 — 三值逻辑和NULL要点应用样例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

SQL查询 — 三值逻辑和NULL

  • 要点
  • 应用样例
    • 1. 排中律
    • 2. CASE表达式和NULL
    • 3. NOT IN 和 NOT EXISTS不是等价的
    • 4. 限定谓词和NULL
    • 5. 极值函数和限定谓词不是等价的
    • 6. 聚合函数和NULL


要点

SQL语言里,有TRUE,FALSE,UNKNOWN三种值,这种逻辑体系被称为三值逻辑(three- valued logic)。因为关系数据库里引进了NULL,所以不得不同时引进第三个值。

  1. IS NULL是判断NULL的正确写法。
  2. 对NULL使用比较谓词后得到的结果总是Unknown。
  3. 包含WHERE子句的查询结果只会包含判断结果为TRUE的行。
  4. NULL 既不是值也不是变量。NULL只是一个表示"没有值"的标记。

以下式子都会被判为Unknown:
           ~~~~~~~~~~            1 = NULL
           ~~~~~~~~~~            2 > NULL
           ~~~~~~~~~~            3 < NULL
           ~~~~~~~~~~            4 <> NULL
           ~~~~~~~~~~            NULL = NULL

  1. 真值unknown是明确的布尔型的真值。
        ~~~    Unknown = Unknown -> TRUE

三值逻辑真值表(NOT)

xNOT x
tf
ft
uu

三值逻辑真值表(AND)
* f > u > t

ANDtuf
ttuf
uuuf
ffff

三值逻辑真值表(OR)
* t > u > f

ORtuf
tttt
utuu
ftuf

应用样例

1. 排中律

Students表有列name,age,其中约翰的年龄为NULL。查询表中的所有行(年龄是20岁或不是20岁或年龄未知的人员记录)。
表Students

nameage
布朗22
拉里19
约翰
伯杰21
SELECT *
FROM Students
WHERE age = 20 OR age <> 20 OR age IS NULL;

2. CASE表达式和NULL

错误写法

CASE col_1
WHEN 1 THEN '0'
WHEN NULL THEN 'X'

正确写法

CASE WHEN col_1 = 1 THEN '0'
WHEN col_1 IS NULL THEN 'X'
END

3. NOT IN 和 NOT EXISTS不是等价的

有两张班级表Class_A,Class_B, 有列name,age,city,其中Class_B中住在东京的山田的age为NULL。查询"与B班住在东京的学生年龄不同的A班学生"。
表Class_A

nameagecity
布朗22东京
拉里19埼玉
伯杰21千叶

表Class_B

nameagecity
齐藤22东京
田尻23东京
山田东京
和泉18千叶
武田20千叶
石川19神奈川

使用NOT IN将查询不到任何结果。如果NOT IN子查询中用到的表里被选择的列中存在NULL,则SQL语句整体查询结果永远是空。

SELECT *
FROM Class_A
WHERE age NOT IN (SELECT age
FROM Class_B
WHERE city = '东京');

* 以上条件相当于WHERE (age <>22) AND (age <>23) AND (age <> NULL)

使用NOT EXISTS可以返回结果。因为EXISTS谓词永远不会返回UNKNOWN,只会返回TRUE或FALSE。

SELECT *
FROM Class_A A
WHERE NOT EXISTS (SELECT *
FROM Class_B B
WHERE A.age = B.age
AND B.city ='东京');

* 子查询没有产生任何结果。因此相反地,NOT EXISTS为TRUE。

4. 限定谓词和NULL

SQL中有ALL和ANY两个限定谓词。因为ANY与IN是等价的,所以我们不经常使用ANY。
接上例,查询比B班住在东京的所有学生年龄都小的A班学生。

SELECT *
FROM Class_A
WHERE age < ALL(SELECT age
FROM Class_B
WHERE city = '东京');

* 若B表中没有空年龄,以上查询能正常显示;若B表中有空年龄,结果不会为True,没有结果返回。
因为ALL谓词其实是多个以AND连接的逻辑表达式的省略写法。即以上条件相当于WHERE (age < 22) AND (age <23) AND (age < NULL)。

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

接上例,查询比B班住在东京的的年龄最小的学生还要小的A班学生。
极值函数在统计时会把为NULL的数据排除掉,在输入为空表(空集)时会返回NULL。

SELECT *
FROM Class_A
WHERE age < (SELECT MIN(age)
FROM Class _B
WHERE city = '东京');

以下在两种情况下,这两种表达是不等价的:

  1. 表里age存在NULL的时候
  2. 谓词(或者函数)的输入为空集的情况,即Class_B表中没有东京学生的情况下。

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

6. 聚合函数和NULL

当输入为空表时返回NULL的不只是极值函数,COUNT以外的聚合函数也是如此。
这种情况的的解决方法只有两种。要么把NULL改成具体值,要么接受NULL。
(如果某列有NOT NULL约束而我们有需要向其中插入聚合值,那么只能选择将NULL改成具体值。)


最后

以上就是糟糕皮卡丘为你收集整理的SQL查询 — 三值逻辑和NULL要点应用样例的全部内容,希望文章能够帮你解决SQL查询 — 三值逻辑和NULL要点应用样例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部