本文介绍如何用 AND
和 OR
操作符组合成 WHERE
子句以建立功能更强、更高级的搜索条件。我们还介绍了如何使用 NOT
和 IN
操作符。
一、组合 WHERE 子句
在 如何使用 SQL WHERE 过滤返回的数据 中介绍的所有 WHERE
子句在过滤数据时使用的都是单一的条件。
为了进行更强的过滤控制,SQL 允许给出多个 WHERE
子句。这些子句有两种使用方式,即以 AND
子句或 OR
子句的方式使用。
1.1 AND 操作符
要通过不止一个列进行过滤,可以使用 AND
操作符给 WHERE
子句附加条件。下面的代码给出了一个例子:
|
|
此 SQL 语句检索由供应商 DLL01
制造且价格小于等于 4
元的所有产品的名称和价格。
这条 SELECT
语句中的 WHERE
子句包含两个条件,用 AND
关键字联结在一起。AND
指示 DBMS 只返回满足所有给定条件的行。
如果某个产品由供应商 DLL01
制造,但价格高于 4
元,则不检索它。
类似地,如果产品价格小于 4
元,但不是由指定供应商制造的也不被检索。这条 SQL 语句产生的输出如下:
|
|
这个例子只包含一个 AND
子句,因此只有两个过滤条件。可以增加多个过滤条件,每个条件间都要使用 AND
关键字。
1.2 OR 操作符
OR
操作符与 AND
操作符正好相反,它指示 DBMS 检索匹配任一条件的行。
事实上,许多 DBMS 在 OR WHERE
子句的第一个条件得到满足的情况下,就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)。
请看如下的 SELECT
语句:
|
|
此 SQL 语句检索由任一个指定供应商制造的所有产品的产品名和价格。
OR
操作符告诉 DBMS 匹配任一条件而不是同时匹配两个条件。
如果这里使用的是 AND
操作符,则没有数据返回(因为会创建没有匹配行的 WHERE
子句)。
这条 SQL 语句产生的输出如下:
|
|
1.3 求值顺序
WHERE
子句可以包含任意数目的 AND
和 OR
操作符。允许两者结合以进行复杂、高级的过滤。但是,组合 AND
和 OR
会带来了一个有趣的问题。为了说明这个问题,来看一个例子。
假如需要列出价格为 10
元及以上,且由 DLL01
或 BRS01
制造的所有产品。下面的 SELECT
语句使用组合的 AND
和 OR
操作符建立了一个 WHERE
子句:
|
|
输出:
|
|
请看上面的结果。返回的行中有 4 行价格小于 10
美元,显然,返回的行未按预期的进行过滤。
为什么会这样呢?原因在于求值的顺序。
SQL(像多数语言一样)在处理 OR
操作符前,优先处理 AND
操作符。
当 SQL 看到上述 WHERE
子句时,它理解为:由供应商 BRS01
制造的价格为 10
元以上的所有产品,以及由供应商 DLL01
制造的所有产品,而不管其价格如何。
换句话说,由于 AND
在求值过程中优先级更高,操作符被错误地组合了。
此问题的解决方法是使用圆括号对操作符进行明确分组。请看下面的 SELECT
语句及输出:
|
|
输出:
|
|
这条 SELECT
语句与前一条的唯一差别是,将前两个条件用圆括号括了起来。
因为圆括号具有比 AND
或 OR
操作符更高的优先级,所以 DBMS 首先过滤圆括号内的 OR
条件。
这时,SQL 语句变成了选择由供应商 DLL01
或 BRS01
制造的且价格在 10
元及以上的所有产品,这正是我们希望的结果。
二、IN 操作符
IN
操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN
取一组由逗号分隔、括在圆括号中的合法值。下面的例子说明了这个操作符。
|
|
输出:
|
|
此 SELECT
语句检索由供应商 DLL01
和 BRS01
制造的所有产品。IN
操作符后跟由逗号分隔的合法值,这些值必须括在圆括号中。
你可能会猜测 IN
操作符完成了与 OR
相同的功能,恭喜你猜对了!下面的 SQL 语句完成与上面的例子相同的工作。
|
|
输出:
|
|
为什么要使用 IN
操作符?其优点如下。
- 在有很多合法选项时,
IN
操作符的语法更清楚,更直观。 - 在与其他
AND
和OR
操作符组合使用IN
时,求值顺序更容易管理。 IN
操作符一般比一组OR
操作符执行得更快(在上面这个合法选项很少的例子中,你看不出性能差异)。IN
的最大优点是可以包含其他SELECT
语句,能够更动态地建立WHERE
子句。SQL 如何使用子查询 对此进行详细介绍。
三、NOT 操作符
WHERE
子句中的 NOT
操作符有且只有一个功能,那就是否定其后所跟的任何条件。因为 NOT
从不单独使用(它总是与其他操作符一起使用),所以它的语法与其他操作符有所不同。
NOT
关键字可以用在要过滤的列前,而不仅是在其后。
下面的例子说明 NOT
的用法。为了列出除 DLL01
之外的所有供应商制造的产品,可编写如下的代码。
|
|
输出:
|
|
这里的 NOT
否定跟在其后的条件,因此,DBMS 不是匹配 vend_id
为 DLL01
,而是匹配非 DLL01
之外的所有东西。
上面的例子也可以使用 <>
操作符来完成,如下所示。
|
|
输出:
|
|
为什么使用 NOT
?对于这里的这种简单的 WHERE
子句,使用 NOT
确实没有什么优势。但在更复杂的子句中,NOT
是非常有用的。
例如,在与 IN
操作符联合使用时,NOT
可以非常简单地找出与条件列表不匹配的行。
四、小结
本文介绍了如何用 AND
和 OR
操作符组合成 WHERE
子句以建立功能更强、更高级的搜索条件。还介绍了如何明确地管理求值顺序,以及如何使用 NOT
和 IN
操作符。
(完)