編寫有效 SQL 查詢的關鍵要素之一是能夠使用 SQL 語法表達各種條件。而能讓資料庫初學者和有經驗的資料庫開發人員停下來思考的一個條件是互斥或(Exclusive OR)。軟體程式設計師往往更熟悉互斥或條件的語法,這可能是因為大多數程式語言都支援 XOR 邏輯運算子,而許多資料庫都不支援。
簡單來說,互斥或條件類似於一般 OR,不同之處在於,互斥或只有一個比較的運算元可能為真,而不是兩個都為真。在這篇文章中,我們將學習如何表達各種資料庫的互斥或條件,無論它們是否支援 XOR 運算子。
使用 XOR 運算子
一些常用的關聯式資料庫(如 MySQL)都支援 XOR 運算子,這使得編寫互斥或條件變得相當簡單。為了舉例說明,設想一下,我們需要找到居住在特定城市內的客戶,或者其帳戶是在特定日期之後建立的,但不會找到同時符合這兩個條件的客戶。更具體地說,我們希望找到居住在亞伯達省萊斯布里奇的客戶,或者,如果他們不居住在萊斯布里奇,他們的帳戶是在 2020 年 1 月 1 日之後建立的。
下面就是使用 Navicat Premium 16 對 Sakila 範例資料庫執行的一個査詢:
查看結果,我們可以看到在 2020-07-07 建立帳戶的第一個客戶的 store_id 為 2,而其餘客戶的 store_id 均為 1(萊斯布里奇店)。
同時,如果我們將一般 OR 取代 XOR,我們現在會看到在 1 號店購物的客戶的帳戶也是在 2020-01-01 之後建立的:
OR 與 XOR 的分別在於允許兩個運算元的計算結果都為 TRUE。
編寫不支援 XOR 的互斥或條件
值得慶幸的是,如果沒有 XOR 運算子,制定互斥或條件並不難。你只需要多考慮一下。從數學上講,x XOR y 等於:
(x AND (NOT y)) OR ((NOT x) AND y)
為了編寫 SQL,我們可以將上述公式簡化為以下形式:
(A OR B) AND NOT (A AND B)
我們將為 SQL Server 重寫第一個查詢來嘗試這個公式。如果我們試圖在該資料庫執行第一個查詢,我們會收到以下錯誤,表示 SQL Server 無法識別 XOR 運算子:
使用上述公式,我們可以將 XOR 條件重寫為:
WHERE (ci.city = 'Lethbridge' OR c.create_date > '2020-01-01') AND NOT (ci.city = 'Lethbridge' AND c.create_date > '2020-01-01')
以下是 SQL Server 中的結果(請注意,兩個資料庫中的資料並不相同):
總結
在今天的文章中,我們學習了如何在各種資料庫中表達互斥或條件,包括使用 XOR 運算子和不使用 XOR 運算子。
如果你想試用一下 Navicat 16,你可以在這裡下載 14 天試用版。