使用 UNION、INTERSECT 和 EXCEPT 對查詢結果執行集合運算
阿新 • • 發佈:2019-02-07
集合運算子和 NULL
集合運算子 UNION、EXCEPT 和 INTERSECT 處理 NULL 的方式與 NULL 在搜尋條件中時處理的方式不同。此差異是使用集合運算子的主要原因之一。
在比較行時,集合運算子將 NULL 值視為彼此相等。相反,在搜尋條件中將 NULL 與 NULL 進行比較時,結果是未知的(不為真)。
此差異的一個特別有用的結果是:query-1 EXCEPT ALL query-2
的結果集中的行數始終 是各個查詢的結果集中的行數之差。
以兩個表 T1 和 T2 為例,其中每個表都具有以下列:
col1 INT, col2 CHAR(1)
表中的資料如下:
-
表 T1。
col1 col2 1 a 2 b 3 (NULL) 3 (NULL) 4 (NULL) 4 (NULL) -
表 T2
col1 col2 1 a 2 x 3 (NULL)
一個詢問同時出現在 T1 和 T2 中的行的查詢如下:
SELECT T1.col1, T1.col2 FROM T1 JOIN T2 ON T1.col1 = T2.col2 AND T1.col2 = T2.col2
T1.col1 | T1.col2 |
---|---|
1 | a |
行 (3, NULL) 不出現在結果集中,因為 NULL 和 NULL 之間的比較不為真。相比之下,使用 INTERSECT 運算子處理該問題,則會包括一個有 NULL 的行:
SELECT col1, col2 FROM T1 INTERSECT SELECT col1, col2 FROM T2
col1 | col2 |
---|---|
1 | a |
3 | (NULL) |
以下查詢使用搜索條件列出 T1 中那些不出現在 T2 中的行:
SELECT col1, col2 FROM T1 WHERE col1 NOT IN ( SELECT col1 FROM t2 WHERE t1.col2 = t2.col2 ) OR col2 NOT IN ( SELECT col2 FROM t2 WHERE t1.col1 = t2.col1 )
col1 | col2 |
---|---|
2 | b |
3 | (NULL) |
4 | (NULL) |
3 | (NULL) |
4 | (NULL) |
比較沒有排除 T1 中包含 NULL 的行。相比之下,使用 EXCEPT ALL 處理該問題會排除在這兩個表中都出現的包含 NULL 的行。在此情況下,會認為 T2 中的 (3, NULL) 行與 T1 中的 (3, NULL) 行相同。
SELECT col1, col2 FROM T1 EXCEPT ALL SELECT col1, col2 FROM T2
col1 | col2 |
---|---|
2 | b |
3 | (NULL) |
4 | (NULL) |
4 | (NULL) |
EXCEPT 運算子仍然有更多的限制。它從 T1 中將兩個 (3, NULL) 行都去除,並將一個 (4, NULL) 行作為重複項排除。
SELECT col1, col2 FROM T1 EXCEPT SELECT col1, col2 FROM T2
col1 | col2 |
---|---|
2 | b |
4 | (NULL) |