sql必知必会系列篇五之高级数据过滤
2022-6-5
| 2023-3-23
0  |  阅读时长 0 分钟
Created time
Jun 5, 2022 01:48 PM
date
status
category
Origin
summary
tags
type
URL
icon
password
slug
这一课讲授如何组合WHERE子句以建立功能更强、更高级的搜索条件。我们还将学习如何使用NOTIN操作符。

组合WHERE子句

篇四介绍的所有WHERE子句在过滤数据时使用的都是单一的条件。为了进行更强的过滤控制,SQL允许给出多个WHERE子句。这些子句有两种使用方式,即以AND子句或OR子句的方式使用。
操作符(operator) 用来联结或改变WHERE子句中的子句的关键字,也称为逻辑操作符(logical operator)。

AND操作符

要通过不止一个列进行过滤,可以使用AND操作符给WHERE子句附加条件。下面的代码给出了一个例子:
输入▼
分析▼ 此SQL语句检索由供应商DLL01制造且价格小于等于4美元的所有品的名称和价格。这条SELECT语句中的WHERE子句包含两个条件,用AND关键字联结在一起。AND指示DBMS只返回满足所有给定条件的行。如果某个产品由供应商DLL01制造,但价格高于4美元,则不检索它。类似地,如果产品价格小于4美元,但不是由指定供应商制造的也不被检索。这条SQL语句产生的输出如下:
AND 用在WHERE子句中的关键字,用来指示检索满足所有给定条件的行。
这个例子只包含一个AND子句,因此最多有两个过滤条件。可以增加多个过滤条件,每个条件间都要使用AND关键字。
说明:没有ORDER BY子句 为了节省空间,也为了减少你的输入,我在很多例子里省略了ORDER BY子句。因此,你的输出完全有可能与书上的输出不一致。虽然返回行的数量总是对的,但它们的顺序可能不同。当然,如果你愿意也可以加上一个ORDER BY子句,它应该放在WHERE子句之后。

OR操作符

OR操作符与AND操作符正好相反,它指示DBMS检索匹配任一条件的行。事实上,许多DBMSOR WHERE子句的第一个条件得到满足的情况下,就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)。
请看如下的SELECT语句:
输入▼
分析▼ 此SQL语句检索由任一个指定供应商制造的所有产品的产品名和价格。OR操作符告诉DBMS匹配任一条件而不是同时匹配两个条件。如果这里使用的是AND操作符,则没有数据返回(因为会创建没有匹配行的WHERE子句)。这条SQL语句产生的输出如下:
ORWHERE子句中使用的关键字,用来表示检索匹配任一给定条件的行。

求值顺序

WHERE子句可以包含任意数目的ANDOR操作符。允许两者结合以进行复杂、高级的过滤。
但是,组合ANDOR会带来了一个有趣的问题。为了说明这个问题,来看一个例子。假如需要列出价格为10美元及以上,且由DLL01BRS01制造的所有产品。下面的SELECT语句使用组合的ANDOR操作建立了一个WHERE子句:
输入▼
输出▼
分析▼ 请看上面的结果。返回的行中有4行价格小于10美元,显然,返回的行未按预期的进行过滤。为什么会这样呢?原因在于求值的顺序。SQL(像多数语言一样)在处理OR操作符前,优先处理AND操作符。当SQL看到上述WHERE子句时,它理解为:由供应商BRS01制造的价格为10美元以上的所有产品,以及由供应商DLL01制造的所有产品,而不管其价格如何。换句话说,由于AND在求值过程中优先级更高,操作符被错误地组合了。
此问题的解决方法是使用圆括号对操作符进行明确分组。请看下面SELECT 语句及输出:
输出▼
分析▼ 这条SELECT语句与前一条的唯一差别是,将前两个条件用圆括号括了起来。因为圆括号具有比ANDOR操作符更高的求值顺序,所以DBMS首先过滤圆括号内的OR条件。这时,SQL语句变成了选择由供应商DLL01BRS01制造的且价格在10美元及以上的所有产品,这正是我们希望的结果。
提示:在WHERE子句中使用圆括号 任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认求值顺序,即使它确实如你希望的那样。使用圆括号没有什么坏处,它能消除歧义。

IN操作符

IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。IN取一组由逗号分隔、括在圆括号中的合法值。下面的例子说明了这个操作符:
输入▼
输出▼
分析▼ 此SELECT语句检索由供应商DLL01BRS01制造的所有产品。IN操作符后跟由逗号分隔的合法值,这些值必须括在圆括号中。
你可能会猜测IN操作符完成了与OR相同的功能,恭喜你猜对了!下面的SQL语句完成与上面的例子相同的工作:
输入▼
输出▼
为什么要使用IN操作符?其优点为:
  • 在有很多合法选项时,IN操作符的语法更清楚,更直观。
  • 在与其他ANDOR操作符组合使用IN时,求值顺序更容易管理。
  • IN操作符一般比一组OR操作符执行得更快(在上面这个合法选项很少的例子中,你看不出性能差异)。
  • IN的最大优点是可以包含其他SELECT语句,能够更动态地建立 WHERE子句。篇11会对此进行详细介绍。
INWHERE子句中用来指定要匹配值的清单的关键字,功能与OR相当。

NOT操作符

WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后所跟的任何条件。因为NOT从不单独使用(它总是与其他操作符一起使用),所以它的语法与其他操作符有所不同。NOT关键字可以用在要过滤的列前,而不仅是在其后。
NOTWHERE子句中用来否定其后条件的关键字。
下面的例子说明NOT的用法。为了列出除DLL01之外的所有供应商制造的产品,可编写如下的代码:
输入▼
输出▼
分析▼ 这里的NOT否定跟在其后的条件,因此,DBMS不是匹配vend_idDLL01,而是匹配非DLL01之外的所有东西。
上面的例子也可以使用 <> 操作符来完成,如下所示:
输入▼
输出▼
分析▼ 为什么使用NOT?对于这里的这种简单的WHERE子句,使用NOT确实没有什么优势。但在更复杂的子句中,NOT是非常有用的。例如,在与IN操作符联合使用时,NOT可以非常简单地找出与条件列表不匹配的行。
说明: MariaDB 中的 NOTMariaDB 支持使用 NOT 否 定 IN 、 BETWEEN 和 EXISTS 子句。大多数 DBMS 允许使用 NOT否定任何条件。

小结

本文讲授如何用 ANDOR 操作符组合成 WHERE 子句,还讲授了如何明确地管理求值顺序,如何使用 INNOT 操作符。
操作系统虚拟化学习笔记(一)|操作系统抽象:进程sql必知必会系列篇四之过滤数据
Loading...