1. 三值邏輯 1.1. 真 1.1.1. true 1.2. 假 1.2.1. false 1.3. 不確定 1.3.1. unknown 2. 兩種NULL 2.1. 未知”(unknown) 2.1.1. 不知道戴墨鏡的人眼睛是什麼顏色 2.1.2. 雖然現在不知道,但加上某些條件後就可以知道 ...
1. 三值邏輯
1.1. 真
- 1.1.1. true
1.2. 假
- 1.2.1. false
1.3. 不確定
- 1.3.1. unknown
2. 兩種NULL
2.1. 未知”(unknown)
-
2.1.1. 不知道戴墨鏡的人眼睛是什麼顏色
-
2.1.2. 雖然現在不知道,但加上某些條件後就可以知道
2.2. “不適用”(not applicable,inapplicable)
-
2.2.1. 不知道冰箱的眼睛是什麼顏色
-
2.2.2. 在語義上更接近於“無意義”
-
2.2.3. 而不是“不確定”
-
2.2.4. 無論怎麼努力都無法知道
2.3. Codd提倡在關係資料庫中使用四值邏輯
- 2.3.1. 現在所有的DBMS都將兩種類型的NULL歸為了一類並採用了三值邏輯
2.4. 資料庫里只要存在一個NULL,查詢的結果就可能不正確
2.5. 最佳方法應該是往表裡添加NOT NULL約束來儘力排除NULL
3. IS NULL
3.1. 謂詞
3.2. 對NULL使用比較謂詞後得到的結果總是unknown
-
3.2.1. --以下的式子都會被判為 unknown
1 = NULL 2 > NULL 3 < NULL 4 <> NULL NULL = NULL
-
3.2.2. 比較謂詞只適用於值
- 3.2.2.1. NULL不是值,所以不能對其使用謂詞
3.3. 查詢結果只會包含WHERE子句里的判斷結果為true的行
- 3.3.1. 不會包含判斷結果為false和unknown的行
3.4. NULL既不是值也不是變數
-
3.4.1. NULL只是一個表示“沒有值”的標記
-
3.4.2. 因為NULL不是值,所以不在定義域(domain)中
3.5. IS NULL這樣的謂詞是由兩個單詞構成的,所以人們容易把IS當作謂詞,而把NULL當作值
4. 三值邏輯
4.1. AND的情況: false > unknown > true
- 4.1.1. 優先順序
4.2. OR的情況: true > unknown > false
- 4.2.1. 優先順序
5. 排中律
5.1. Law of Excluded Middle
5.2. “把命題和它的否命題通過‘或者’連接而成的命題全都是真命題”這個命題在二值邏輯中被稱為排中律
5.3. 在SQL的世界里,排中律是不成立的
5.4. 示例
-
5.4.1. --查詢年齡是20歲或者不是20歲的學生
SELECT * FROM Students WHERE age = 20 OR age <> 20;
-
5.4.2. --1.約翰年齡是NULL(未知的NULL!
SELECT * FROM Students WHERE age = NULL OR age <> NULL;
-
5.4.3. --2.對NULL使用比較謂詞後,結果為unknown
SELECT * FROM Students WHERE unknown OR unknown;
-
5.4.4. --3.unknown OR unknown的結果是unknown
SELECT * FROM Students WHERE unknown;
-
5.4.5. SQL語句的查詢結果里只有判斷結果為true的行
- 5.4.5.1. --添加第3個條件:年齡是20歲,或者不是20歲,或者年齡未知
SELECT * FROM Students WHERE age = 20 OR age <> 20 OR age IS NULL;
6. CASE表達式
6.1. 示例
-
6.1.1. --col_1為1時返回○、為NULL時返回×的CASE表達式?
CASE col_1 WHEN 1 THEN'○' WHEN NULL THEN'×' END
-
6.1.2. CASE表達式一定不會返回×
- 6.1.2.1. 第二個WHEN子句是col_1 = NULL的縮寫形式
-
6.1.3.
CASE WHEN col_1 = 1 THEN'○' WHEN col_1 IS NULL THEN'×' END
6.2. CASE表達式的判斷方法與WHERE子句一樣,只認可真值為true的條件
7. NOT EXISTS
7.1. IN改寫成EXISTS是等價改寫
7.2. NOT IN和NOT EXISTS不是等價的
7.3. 示例
-
7.3.1. B班山田的年齡是NULL
-
7.3.2. --查詢與B班住在東京的學生年齡不同的A班學生的SQL語句?
SELECT * FROM Class_A WHERE age NOT IN ( SELECT age FROM Class_B WHERE city =’東京’);
- 7.3.2.1. 結果是空,查詢不到任何數據
-
7.3.3. --正確的SQL語句:拉里和伯傑將被查詢到
SELECT * FROM Class_A A WHERE NOT EXISTS ( SELECT * FROM Class_B B WHERE A.age = B.age AND B.city = ’東京’);
-
7.3.4. --1.執行子查詢,獲取年齡列表
SELECT * FROM Class_A WHERE age NOT IN (22, 23, NULL);
- 7.3.4.1. --1.在子查詢里和NULL進行比較運算
SELECT * FROM Class_A A WHERE NOT EXISTS ( SELECT * FROM Class_B B WHERE A.age = NULL AND B.city =’東京’);
-
7.3.5. --2.用NOT和IN等價改寫NOT IN
SELECT * FROM Class_A WHERE NOT age IN (22, 23, NULL);
- 7.3.5.1. --2.對NULL使用“=”後,結果為 unknown
SELECT * FROM Class_A A WHERE NOT EXISTS ( SELECT * FROM Class_B B WHERE unknown AND B.city =’東京’);
-
7.3.6. --3.用OR等價改寫謂詞IN
SELECT * FROM Class_A WHERE NOT ( (age = 22) OR (age = 23) OR (age = NULL) );
- 7.3.6.1. --3.如果AND運算里包含unknown,結果不會是true
SELECT * FROM Class_A A WHERE NOT EXISTS ( SELECT * FROM Class_B B WHERE false或unknown);
-
7.3.7. --4.使用德·摩根定律等價改寫
SELECT * FROM Class_A WHERE NOT (age = 22) AND NOT(age = 23) AND NOT (age = NULL);
- 7.3.7.1. --3.如果AND運算里包含unknown,結果不會是true
SELECT * FROM Class_A A WHERE NOT EXISTS ( SELECT * FROM Class_B B WHERE false或unknown);
- 7.3.7.2. 山田被作為“與任何人的年齡都不同的人”來處理了
-
7.3.8. --5.用<>等價改寫NOT和=
SELECT * FROM Class_A WHERE (age <> 22) AND (age <> 23) AND (age <> NULL);
-
7.3.9. --6.對NULL使用<>後,結果為unknown
SELECT * FROM Class_A WHERE (age <> 22) AND (age <> 23) AND unknown;
-
7.3.10. --7.如果AND運算里包含unknown,則結果不為true
SELECT * FROM Class_A WHERE false或unknown;
7.4. EXISTS謂詞永遠不會返回unknown
- 7.4.1. EXISTS只會返回true或者false
8. ALL謂詞
8.1. 多個以AND連接的邏輯表達式的省略寫法
8.2. 與IN是等價的,所以我們不經常使用ANY
8.3. 示例
-
8.3.1. --查詢比B班住在東京的所有學生年齡都小的A班學生
SELECT * FROM Class_A WHERE age < ALL ( SELECT age FROM Class_B WHERE city =’東京’);
- 8.3.1.1. 他的年齡比在東京住的所有學生都小
-
8.3.2.
--1.執行子查詢獲取年齡列表 SELECT * FROM Class_A WHERE age < ALL ( 22, 23, NULL ); --2.將ALL謂詞等價改寫為AND SELECT * FROM Class_A WHERE (age < 22) AND (age < 23) AND (age < NULL); --3.對NULL使用“<”後,結果變為 unknown SELECT * FROM Class_A WHERE (age < 22) AND (age < 23) AND unknown; --4. 如果AND運算里包含unknown,則結果不為true SELECT * FROM Class_A WHERE false 或 unknown;
9. 極值函數
9.1. --查詢比B班住在東京的年齡最小的學生還要小的A班學生
SELECT *
FROM Class_A
WHERE age < ( SELECT MIN(age)
FROM Class_B
WHERE city =’東京’);
- 9.1.1. 他的年齡比在東京住的年齡最小的學生還要小
9.2. 限定謂詞和極值函數不是等價的
9.3. 極值函數在統計時會把為NULL的數據排除掉
9.4. 極值函數在輸入為空表(空集)時會返回NULL
-
9.4.1.
--1.極值函數返回NULL SELECT * FROM Class_A WHERE age < NULL; --2.對NULL使用“<”後結果為 unknown SELECT * FROM Class_A WHERE unknown;
10. 聚合函數
10.1. COUNT以外的聚合函數當輸入為空表時返回NULL
10.2. 示例
-
10.2.1. --查詢比住在東京的學生的平均年齡還要小的A班學生的SQL語句?
SELECT * FROM Class_A WHERE age < ( SELECT AVG(age) FROM Class_B WHERE city =’東京’);
-
10.2.2. 沒有住在東京的學生時,AVG函數返回NULL
-
10.2.3. 外側的WHERE子句永遠是unknown,也就查詢不到行