SELECT product_name, product_type, sale_price
FROM Product
WHERE sale_price >= 1000;
product_name | product_type | sale_price |
---|---|---|
T恤衫 | 衣服 | 1000 |
运动T恤 | 衣服 | 4000 |
菜刀 | 厨房用具 | 3000 |
高压锅 | 厨房用具 | 6800 |
Rui
November 10, 2022
除了上一节介绍的 <> 比较运算符以外,NOT 运算符也可以表示否定,但需要同其他查询条件联用:
product_name | product_type | sale_price |
---|---|---|
T恤衫 | 衣服 | 1000 |
运动T恤 | 衣服 | 4000 |
菜刀 | 厨房用具 | 3000 |
高压锅 | 厨房用具 | 6800 |
添加 NOT:
product_name | product_type | sale_price |
---|---|---|
打孔器 | 办公用品 | 500 |
叉子 | 厨房用具 | 500 |
擦菜板 | 厨房用具 | 880 |
圆珠笔 | 办公用品 | 100 |
等价于:
product_name | product_type | sale_price |
---|---|---|
打孔器 | 办公用品 | 500 |
叉子 | 厨房用具 | 500 |
擦菜板 | 厨房用具 | 880 |
圆珠笔 | 办公用品 | 100 |
在 WHERE 子句中使用 AND 和 OR 来组合多个条件:
AND 运算符代表”和”,只有两侧条件同时为真时才返回真。从集合的视角看,相当于取交集
OR 运算符代表”或”,只要两侧条件中有一个为真就返回真。从集合的视角看,相当于取并集
查询条件:“商品种类为办公用品”并且”登记日期是2009年9月11日或者2009年9月20日”
查询结果:符合上述条件的商品(product_name)只有”打孔器”
错误的方法:
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND regist_date = '2009-09-11'
OR regist_date = '2009-09-20';
product_name | product_type | regist_date |
---|---|---|
T恤衫 | 衣服 | 2009-09-20 |
打孔器 | 办公用品 | 2009-09-11 |
菜刀 | 厨房用具 | 2009-09-20 |
叉子 | 厨房用具 | 2009-09-20 |
这是因为 AND 在前 OR 在后导致 AND 的优先级比 OR 高,该查询的过程是先实现 AND 查询,再在 AND 查询的结果中实现 OR 查询。
正确的做法:
SELECT product_name, product_type, regist_date
FROM Product
WHERE product_type = '办公用品'
AND (regist_date = '2009-09-11'
OR regist_date = '2009-09-20');
product_name | product_type | regist_date |
---|---|---|
打孔器 | 办公用品 | 2009-09-11 |
使用括号提高 OR 的优先级。
真 = TRUE = 1
假 = FALSE = 0
P | Q | 积 | P AND Q |
---|---|---|---|
1 | 1 | 1 | 1 |
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 0 | 0 |
P | Q | 和 | P OR Q |
---|---|---|---|
1 | 1 | 1 + 1 | 1 |
1 | 0 | 1 | 1 |
0 | 1 | 1 | 1 |
0 | 0 | 0 | 0 |
由 OR 的定义可知:真 + 假 = 1 + 0 = 1.
所以:真 = 1 - 假 = 1 - 0 = 1,假 = 1 - 真 = 1 - 1 = 0.
P | 差 | NOT P |
---|---|---|
1 | 1 - 1 | 0 |
0 | 1 - 0 | 1 |
上一节讲过对于 NULL 的比较运算使用 IS NULL 或者 IS NOT NULL,其逻辑运算一样特殊。
注意到商品”叉子”和”圆珠笔”的价格都为 NULL,若对这两条记录使用查询条件 purchase_price = 2800
则返回假;但若对这两条记录使用查询条件 NOT purchase_price = 2800
则还是返回假。也就是说对于 purchase_price = 2800
,结果既非真又非假。
这种情况是 SQL 中的除真假之外的第三种值——不确定(UNKNOWN)。 一般的逻辑运算为二值运算,SQL 中的逻辑运算为三值运算。
如何理解:
真(1)和假(0)都是确定的状态,而 NULL 是不确定的状态(混沌的)。NULL 就像薛定谔的猫,不到打开箱子看到它的真面目时谁也不知道它是真是假,只有打开箱子的那一刹那才能获知它的状态,但是那时它就不是 UNKNOWN 了;
一个 NULL 和一个确定的数值进行比较判断,结果自然是不确定的(UNKNOWN)。同理一个 NULL 与另一个 NULL 进行比较判断,结果还是不确定的(UNKNOWN);
那么包含 NULL 的逻辑判断是怎样的呢?其实利用 AND 与 OR 的定义结合 NULL 的特性不难得出:
P | Q | P AND Q |
---|---|---|
真 | 真 | 真 |
真 | 假 | 假 |
真 | 不确定 | 不确定 |
假 | 真 | 假 |
假 | 假 | 假 |
假 | 不确定 | 假 |
不确定 | 真 | 不确定 |
不确定 | 假 | 假 |
不确定 | 不确定 | 不确定 |
P | Q | P OR Q |
---|---|---|
真 | 真 | 真 |
真 | 假 | 真 |
真 | 不确定 | 真 |
假 | 真 | 真 |
假 | 假 | 假 |
假 | 不确定 | 不确定 |
不确定 | 真 | 真 |
不确定 | 假 | 不确定 |
不确定 | 不确定 | 不确定 |
可以看出,在引入”不确定”后,逻辑判断变得复杂许多。为了避免出现这种情况,一般在创建表的时候为某些列设置 NOT NULL 约束以禁止录入 NULL。