编写有效 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(莱斯布里奇店)。
同时,如果我们将 XOR 替换为常规 OR,我们现在会看到在 1 号店购物的客户的帐户也是在 2020-01-01 之后创建的:
允许两个操作数计算结果为 TRUE 是 OR 与 XOR 的区别。
编写不支持 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 运算符。
如果你想试一下 Navicat 16,你可以在这里下载 14 天试用版。