product_name | product_type | regist_date
---------------+--------------+------------
打孔器 | 办公用品 | 2009-09-11
这样就选取出了想要得到的“打孔器”。
法则 13
AND
运算符的优先级高于 OR
运算符。想要优先执行 OR
运算符时需要使用括号。
3.4 逻辑运算符和真值
本节介绍的三个运算符 NOT
、AND
和 OR
称为逻辑运算符。这里所说的逻辑就是对真值进行操作的意思。真值就是值为 真(TRUE) 或 假(FALSE) 其中之一的值 。
上一节介绍的比较运算符会把运算结果以真值的形式进行返回。比较结果成立时返回真(TRUE
),比较结果不成立时返回假(FALSE
)。
例如,对于 purchase_price >= 3000
这个查询条件来说,由于 product_name
列为 '运动 T 恤'
的记录的 purchase_price
列的值是 2800
,因此会返回假(FALSE
),而 product_name
列为 '高压锅'
的记录的 purchase_price
列的值是 5000
,所以返回真(TRUE
)。
逻辑运算符对比较运算符等返回的真值进行操作。AND
运算符两侧的真值都为真时返回真,除此之外都返回假。
OR
运算符两侧的真值只要有一个不为假就返回真,只有当其两侧的真值都为假时才返回假。
NOT
运算符只是单纯的将真转换为假,将假转换为真。真值表(truth table)就是对这类操作及其结果进行的总结(表 4)。
表 4 真值表
P AND Q
请将表 4 中的 P
和 Q
想象为“销售单价为 500
元”这样的条件。逻辑运算的结果只有真和假两种,对其进行排列组合将会得到 2 × 2 = 4
种结果。
在 SELECT
语句的 WHERE
子句中,通过 AND
运算符将两个查询条件连接起来时,会查询出这两个查询条件都为真的记录。
通过 OR
运算符将两个查询条件连接起来时,会查询出某一个查询条件为真或者两个查询条件都为真的记录。
在条件表达式中使用 NOT
运算符时,会选取出查询条件为假的记录(反过来为真)。
虽然表 4 中的真值表只是使用一个逻辑运算符时得到的结果,但即使使用两个以上的逻辑运算符连接三个以上的查询条件,通过反复进行逻辑运算求出真值,不论多复杂的条件也可以得到相应的结果。
表 5 就是根据之前例子中的查询条件“商品种类为办公用品”,并且“登记日期是 2009 年 9 月 11 日 或者 2009 年 9 月 20 日”(product_type = '办公用品' AND (regist_date = '2009-09-11' OR regist_date = '2009-09-20')
)做成的真值表。
表 5 查询条件为 P AND(Q OR R)的真值表
P AND (Q OR R)
Q OR R
P AND (Q OR R)
Q:登记日期是 2009 年 9 月 11 日
R:登记日期是 2009 年 9 月 20 日
Q OR
R:登记日期是 2009 年 9 月 11 日 或者 2009 年 9 月 20 日
P AND
(Q OR
R):商品种类为办公用品,并且,登记日期是 2009 年 9 月 11 日 或者 2009 年 9 月 20 日
代码清单 36 中的 SELECT
语句,查询出了唯一满足 P AND
(Q OR
R) 为真的记录“打孔器”。
法则 14
通过创建真值表,无论多复杂的条件,都会更容易理解。
逻辑积与逻辑和
将表 4 的真值表中的真变为 1
、假变为 0
,意外地得到了下述规则。
表 A 真为 1、假为 0 的真值表
AND(逻辑积)
P AND Q
NOT
运算符并没有什么特别的改变,但是 AND
运算的结果与乘法运算(积),OR
运算的结果与加法运算(和)的结果却是一样的。
严格来说,此处的 1+1=1
与通常的整数运算并不相同。只是因为真值中只存在 0
和 1
两种情况,所以才有了这样的结果。
因此,使用 AND
运算符进行的逻辑运算称为逻辑积,使用 OR
运算符进行的逻辑运算称为逻辑和。
3.5 含有 NULL 时的真值
上一节我们介绍了查询 NULL
时不能使用比较运算符(=
或者 <>
),需要使用 IS NULL
运算符或者 IS NOT NULL
运算符。实际上,使用逻辑运算符时也需要特别对待 NULL
。
我们来看一下 Product
(商品)表,商品“叉子”和“圆珠笔”的进货单价(purchase_price
)为 NULL
。
那么,对这两条记录使用查询条件 purchase_price = 2800
(进货单价为 2800
元)会得到什么样的真值呢?如果结果为真,则通过该条件表达式就可以选取出“叉子”和“圆珠笔”这两条记录。
但是在之前介绍“不能对 NULL
使用比较运算符”(第 2 节)时,我们就知道结果并不是这样的,也就是说结果不为真。
那结果会为假吗?实际上结果也不是假。
如果结果为假,那么对其进行否定的条件 NOT purchase_price = 2800
(进货单价不是 2800
元)的结果应该为真,也就能选取出这两条记录了(因为假的对立面为真),但实际结果却并不是这样。
既不是真也不是假,那结果到底是什么呢?其实这是 SQL 中特有的情况。这时真值是除真假之外的第三种值——不确定(UNKNOWN
)。一般的逻辑运算并不存在这第三种值。
SQL 之外的语言也基本上只使用真和假这两种真值。与通常的逻辑运算被称为二值逻辑相对,只有 SQL 中的逻辑运算被称为三值逻辑。
因此,表 4 中的真值表并不完整,完整的真值表应该像表 6 这样包含“不确定”这个值。
表 6 三值逻辑中的 AND 和 OR 真值表
P AND Q
Product 表中设置 NOT NULL 约束的原因
原本只有 4 行的真值表,如果要考虑 NULL
的话就会像表 6 那样增加为 3×3=9
行,看起来也变得更加繁琐,考虑 NULL
时的条件判断也会变得异常复杂,这与我们希望的结果大相径庭。
因此,数据库领域的有识之士们达成了“尽量不使用 NULL
”的共识。
这就是为什么在创建 Product
表时要给某些列设置 NOT NULL
约束(禁止录入 NULL
)的缘故。
原文链接:https://www.developerastrid.com/sql/sql-select-where/