04-06章 过滤数据

第4章 过滤数据

4.1 WHERE 子句

根据需要提取表数据的子集,需要指定搜索条件(search criteria)。

  • 在 SELECT 语句中,数据根据 WHERE 子句中指定的搜索条件进行过滤。
  • WHERE 子句在表名(FROM 子句)之后给出。
SELECT prod_name, prod_price FROM Products
WHERE prod_price = 3.49;

分析
这条语句从 products 表中检索两个列,但不返回所有行,只返回 prod_price 值为 3.49 的行,输出:

04-06章 过滤数据_第1张图片
屏幕快照 2018-05-27 08.32.33.png

注意
同时使用 ORDER BY 和 WHERE 子句时,ORDER BY 应位于 WHERE 之后,否则将出错。

4.2 WHERE 子句操作符

操作符 说明 操作符 说明
= 等于 > 大于
<> 不等于 >= 大于等于
!= 不等于 !> 不大于
< 小于 BETWEEN 在指定的两个值之间
<= 小于等于 IS NULL 为NULL值
!< 不小于

检查单个值
列出所有价格小于等于 10 美元的产品。

SELECT prod_name, prod_price FROM Products
WHERE prod_price <= 10;
04-06章 过滤数据_第2张图片
屏幕快照 2018-05-27 08.52.12.png

不匹配检查
列出所有不是供应商 DLL01 制造的产品:

SELECT vend_id, prod_name FROM Products
WHERE vend_id <> 'DLL01';
04-06章 过滤数据_第3张图片
屏幕快照 2018-05-27 08.56.58.png

注意:何时使用引号
上述 WHERE 子句中的条件,有的值括在单引号内,而有的值未括起来。

  • 单引号用来限定字符串。
  • 将值与字符串类型的列进行比较,就要限定引号。
  • 将值与数值列进行比较,不用引号。

范围值检索
要检查某个范围的值,使用 BETWEEN 操作符。其语法与其他 WHERE 子句的操作符稍有不同,因为它需要两个值,即范围的开始值和结束值。

例如,BETWEEN 操作符可用来检索价格在 5 美元和 10 美元之间的所有产品,或在指定的开始日期和结束日期之间的所有日期。

SELECT prod_name, prod_price FROM Products
WHERE prod_price BETWEEN 5 AND 10;
04-06章 过滤数据_第4张图片
屏幕快照 2018-05-27 10.51.33.png

空值检查
在创建表时,表设计人员可以指定其中的列能否不包含值。在一个列不包含值时,称其包含空值 NULL。确定值是否为 NULL,用 IS NULL 子句。

SELECT prod_name FROM Products
WHERE prod_price IS NULL;

这条语句返回所有没有价格(空 prod_price 字段,不是价格为 0)的产品。
但是,Customers 表包含具有 NULL 值的列:如果没有电子邮件地址,则 cust_email 列将包含 NULL 值:

SELECT cust_name FROM Customers
WHERE cust_email IS NULL;
04-06章 过滤数据_第5张图片
屏幕快照 2018-05-27 10.58.20.png

第5章 高级数据过滤

5.1 组合 WHERE 子句

SQL 允许给出多个 WHERE 子句,这些子句有两种使用方式,即以 AND 子句或 OR 子句的方式使用。

AND 操作符

SELECT prod_id, prod_price, prod_name FROM Products
WHERE vend_id = 'DLL01' AND prod_price <= 4;

此 SQL 语句检索由供应商 DLL01 制造且价格小于等于 4 美元的所有产品的名称和价格。


04-06章 过滤数据_第6张图片
屏幕快照 2018-05-27 11.03.13.png

OR 操作符
许多 DBMS 在 OR WHERE 子句的第一个条件得到满足的情况下,就不再计算第二个条件了(在第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)。

SELECT prod_name, prod_price FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
04-06章 过滤数据_第7张图片
屏幕快照 2018-05-27 11.06.50.png

求值顺序
需要列出价格为10美元及以上,且由 DLL01 或 BRS01 制造的所有产品。

SELECT prod_name, prod_price FROM Products
WHERE vend_id = 'DLL01' OR vend_id = 'BRS01'
      AND prod_price >= 10;
04-06章 过滤数据_第8张图片
屏幕快照 2018-05-27 11.11.10.png

上面结果返回的行中有 4 行价格小于 10 美元,原因在于求值的顺序。

  • SQL 在处理 OR 操作符前,优先处理 AND 操作符。
  • SQL 理解 WHERE 子句为:由供应商 BRS01 制造的价格为 10 美元以上的所有产品,以及由供应商 DLL01 制造的所有产品,而不管其价格如何。
  • 由于 AND 在求值过程中优先级更高,操作符被错误地组合。

此问题的解决方法是使用圆括号对操作符进行明确分组:

SELECT prod_name, prod_price FROM Products
WHERE (vend_id = 'DLL01' OR vend_id= 'BRS01')
      AND prod_price >= 10;
04-06章 过滤数据_第9张图片
屏幕快照 2018-05-27 11.17.33.png

将前两个条件用圆括号括起来,因为圆括号具有比 AND 或 OR 操作符更高的求值顺序,所以 DBMS 首先过滤圆括号内的 OR 条件。

注意
任何时候使用具有 AND 和 OR 操作符的 WHERE 子句,都要使用圆括号分组操作符。

5.2 IN 操作符

IN 操作符用来指定条件范围,一组由逗号分隔括在圆括号中的合法值,范围中的每个条件都可以进行匹配,与 OR 功能相同。

SELECT prod_name, prod_price FROM Products
WHERE vend_id IN ('DLL01', 'BRS01')
ORDER BY prod_name;
04-06章 过滤数据_第10张图片
屏幕快照 2018-05-27 11.26.02.png

IN 操作符的优点

  • IN 操作符的语法更清楚直观。
  • 在与其他 AND 和 OR 操作符组合使用 IN 时,求值顺序更容易管理。
  • IN 操作符一般比一组 OR 操作符执行得更快。
  • IN 可以包含其他 SELECT 语句, 能够更动态地建立 WHERE 子句。

5.3 NOT 操作符

WHERE 子句中的 NOT 操作符只有一个功能,否定其后所跟的任何条件。列出除 DLL01 之外的所有供应商制造的产品:

SELECT prod_name FROM Products
WHERE NOT vend_id= 'DLL01' ORDER BY prod_name;
04-06章 过滤数据_第11张图片
屏幕快照 2018-05-27 11.32.56.png

第6章 用通配符进行过滤

6.1 LIKE 操作符

通配符(wildcard)用来匹配值的一部分的特殊字符。
搜索模式(search pattern)由字面值、通配符或两者组合构成的搜索条件。

通配符实际上是 SQL 的 WHERE 子句中有特殊含义的字符。为在搜索子句中使用通配符,必须使用 LIKE 操作符。LIKE 指示 DBMS,后跟的搜索模式利用通配符匹配而不是简单的相等匹配进行比较。

百分号(%)通配符
在搜索串中,%表示任何字符出现任意次数。要找出所有以词 Fish 开头的产品:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE 'Fish%'
04-06章 过滤数据_第12张图片
屏幕快照 2018-05-27 12.25.46.png

在执行这条子句时,将检索任意以 Fish 起头的词。%告诉 DBMS 接受 Fish 之后的任意字符,不管它有多少字符。

通配符可在搜索模式中的任意位置使用,并且可以使用多个通配符。例子使用两个通配符,它们位于模式的两端:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '%bean bag%';
04-06章 过滤数据_第13张图片
屏幕快照 2018-05-27 12.30.15.png

注意
包括 Access 在内的许多 DBMS 都用空格来填补字段的内容。
例如,如果某列有 50 个字符,而存储的文本为 Fish bean bag toy(17 个字符),则为填满该列需要在文本后附加 33 个空格。这样做一般对数据及其使用没有影响,但是可能对上述 SQL语句有负面影响。

子句WHERE prod_name LIKE 'F%y'只匹配以 F 开头以 y 结尾的 prod_name。如果值后面跟空格,则不是以 y 结尾,所以 Fish bean bag toy 就不会检索出来。

解决办法:给搜索模式再增加一个%号,'F%y%'还匹配 y 之后的字符或空格。

注意
通配符%不能匹配 NULL,子句WHERE prod_name LIKE '%'不匹配产品名称为 NULL 的行。

下划线(_)通配符
下划线的用途与%一样,但只匹配单个字符,而不是多个字符。

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '__ inch teddy bear';
04-06章 过滤数据_第14张图片
屏幕快照 2018-05-27 12.40.46.png

下面 SELECT 语句使用%通配符,返回三行产品:

SELECT prod_id, prod_name FROM Products
WHERE prod_name LIKE '% inch teddy bear';
04-06章 过滤数据_第15张图片
屏幕快照 2018-05-27 12.43.25.png

方括号([ ])通配符
方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。目前只有 Access 和 SQL Server 支持集合。

例如找出所有名字以 J 或 M 起头的联系人:

SELECT cust_contact FROM Customers
WHERE cust_contact LIKE '[JM]%' ORDER BY cust_contact;
04-06章 过滤数据_第16张图片
屏幕快照 2018-05-27 12.49.26.png

此语句的 WHERE 子句中的模式为'[JM]%',这一搜索模式使用了两个不同的通配符。[JM]匹配方括号中任意一个字符,它也只能匹配单个字符。

此通配符可以用前缀字符(脱字号)来否定。例如,查询以 J 和 M 之外的任意字符起头的任意联系人名:

SELECT cust_contact FROM Customers
WHERE cust_contact LIKE '[^JM]%' ORDER BY cust_contact;

也可以使用 NOT 操作符得出类似的结果:

SELECT cust_contact FROM Customers
WHERE NOT cust_contact LIKE '[JM]%' ORDER BY cust_contact;

6.2 使用通配符的技巧

  1. 如果其他操作符能达到相同的目的,应该使用其他操作符。
  2. 确实需要使用通配符时,不要把它们用在搜索模式的开始处,会非常慢。
  3. 如果通配符放错地方,不会返回想要的数据。

你可能感兴趣的:(04-06章 过滤数据)