读书笔记:SQL必知必会【第4课~第6课】

第4课 过滤数据

这一课程讲授如何使用SELECT语句的WHERE子句指定搜索条件。

4.1 使用WHERE子句

数据库表一般包含大量的数据,很少需要检索表中的所有行,通常只会根据特定操作或报告的需要提取表数据的子集,只检索所需数据需要指定搜索条件,也称为过滤条件。

在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤,WHERE子句在表名(FROM子句)之后给出,如下所示:

mysql> SELECT prod_name, prod_price
    -> FROM Products
    -> WHERE prod_price = 3.49
    -> ;
+---------------------+------------+
| prod_name           | prod_price |
+---------------------+------------+
| Fish bean bag toy   |       3.49 |
| Bird bean bag toy   |       3.49 |
| Rabbit bean bag toy |       3.49 |
+---------------------+------------+
3 rows in set (0.00 sec)

这条语句从Products表中检索两个列,但不返回所有行,只返回prod_price值为3.49的行。使用了简单地相等检验:检查这一列的值是否为指定值,据此过滤数据。

在同时应用WHERE子句和ORDER BY子句的时候,应当让ORDER BY子句位于WHERE之后,否则会产生错误。

4.2 WHERE子句操作符

下表列出了SQL支持的所有WHERE子句条件操作符:

这里写图片描述

4.2.1 检查单个值

我们已经看了检验相等的例子,现在看看其他使用操作符的例子:列出所有价格小于10美元的产品:

mysql> SELECT prod_id, prod_price
    -> FROM Products
    -> WHERE prod_price < 10;
+---------+------------+
| prod_id | prod_price |
+---------+------------+
| BNBG01  |       3.49 |
| BNBG02  |       3.49 |
| BNBG03  |       3.49 |
| BR01    |       5.99 |
| BR02    |       8.99 |
| RGAN01  |       4.99 |
| RYL01   |       9.49 |
| RYL02   |       9.49 |
+---------+------------+
8 rows in set (0.00 sec)

4.2.2 不匹配检查

这个例子列出所有不是供应商DLL01制造的产品:

mysql> SELECT prod_id, vend_id
    -> FROM Products
    -> WHERE vend_id != 'DLL01';
+---------+---------+
| prod_id | vend_id |
+---------+---------+
| BR01    | BRS01   |
| BR02    | BRS01   |
| BR03    | BRS01   |
| RYL01   | FNG01   |
| RYL02   | FNG01   |
+---------+---------+
5 rows in set (0.00 sec)

4.2.3 范围值检查

要检查某个范围的值,可以使用BETWEEN操作符,其语法与其他WHERE子句的操作符稍微不同,因为它需要两个值,即范围的开始值和结束值。例如,BETWEEN操作符可用来检索价格在5美元和10美元之间的所有产品,或在指定的开始日期和结束日期之间的所有日期。

下面的例子检索价格在5美元和10美元之间的所有产品:

mysql> SELECT prod_name, prod_price
    -> FROM Products
    -> WHERE prod_price BETWEEN 5 AND 10;
+--------------------+------------+
| prod_name          | prod_price |
+--------------------+------------+
| 8 inch teddy bear  |       5.99 |
| 12 inch teddy bear |       8.99 |
| King doll          |       9.49 |
| Queen doll         |       9.49 |
+--------------------+------------+
4 rows in set (0.00 sec)

BETWEEN范围匹配所有的值,包括命令指定的开始值和结束值(本例为5和10)。

4.2.4 空值检查

在创建表时,表设计人员可以指定其中的列能否不包含值,当一个列不包含值,称其包含空值NULL。

确定值是否为NULL,不能简单检查是否=NULL,SELECT语句由一个特殊的WHERE子句,可用来检查具有NULL值的列,这个WHERE子句就是IS NULL子句,语法如下:

mysql> SELECT prod_name
    -> FROM Products
    -> WHERE prod_price IS NULL;
Empty set (0.00 sec)

由于原表中不存在prod_price列空值的项,因此返回empty。

但是,CUSTOMER表中是含有NULL列的:

mysql> SELECT * FROM CUSTOMERS
    -> ;
+------------+---------------+----------------------+-----------+------------+----------+--------------+--------------------+-----------------------+
| cust_id    | cust_name     | cust_address         | cust_city | cust_state | cust_zip | cust_country | cust_contact       | cust_email            |
+------------+---------------+----------------------+-----------+------------+----------+--------------+--------------------+-----------------------+
| 1000000001 | Village Toys  | 200 Maple Lane       | Detroit   | MI         | 44444    | USA          | John Smith         | sales@villagetoys.com |
| 1000000002 | Kids Place    | 333 South Lake Drive | Columbus  | OH         | 43333    | USA          | Michelle Green     | NULL                  |
| 1000000003 | Fun4All       | 1 Sunny Place        | Muncie    | IN         | 42222    | USA          | Jim Jones          | jjones@fun4all.com    |
| 1000000004 | Fun4All       | 829 Riverside Drive  | Phoenix   | AZ         | 88888    | USA          | Denise L. Stephens | dstephens@fun4all.com |
| 1000000005 | The Toy Store | 4545 53rd Street     | Chicago   | IL         | 54545    | USA          | Kim Howard         | NULL                  |
+------------+---------------+----------------------+-----------+------------+----------+--------------+--------------------+-----------------------+
5 rows in set (0.00 sec)

因此可以查询空值:

mysql> SELECT cust_name , cust_email
    -> FROM Customers
    -> WHERE cust_email IS NULL;
+---------------+------------+
| cust_name     | cust_email |
+---------------+------------+
| Kids Place    | NULL       |
| The Toy Store | NULL       |
+---------------+------------+
2 rows in set (0.00 sec)

第5课 高级数据过滤

这一课讲授如何组合WHERE子句以建立功能更强,更高级的搜索条件,还将学习如何使用NOT和IN操作符。

5.1 组合WHERE子句

第4课介绍的所有WHERE子句在过滤数据时,使用的都是单一的条件,为了进行更强的过滤控制,SQL允许给出多个WHERE子句,这些WHERE子句有两种使用方式,即AND和OR子句的方式。

5.1.1 AND操作符

要通过不止一个列进行过滤,可以使用AND操作符给WHERE子句附加条件:

mysql> SELECT prod_id,prod_price,prod_name
    -> FROM Products
    -> WHERE vend_id = 'DLL01' AND prod_price <= 4;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name           |
+---------+------------+---------------------+
| BNBG01  |       3.49 | Fish bean bag toy   |
| BNBG02  |       3.49 | Bird bean bag toy   |
| BNBG03  |       3.49 | Rabbit bean bag toy |
+---------+------------+---------------------+
3 rows in set (0.00 sec)

这里使用AND子句,将两个WHERE子句的过滤条件连接在一起,返回同时满足两个条件的行。
本例只有一个AND子句,支持两个过滤条件。实际应用也可以增加多个过滤条件,每个条件间都用AND相连。

5.1.2 OR操作符

OR操作符与AND操作符正好相反,它指示DBMS检索匹配任一条件的行:

mysql> SELECT prod_name,prod_price
    -> FROM Products
    -> WHERE vend_id = 'DLL01' OR vend_id = 'BRS01';
+---------------------+------------+
| prod_name           | prod_price |
+---------------------+------------+
| Fish bean bag toy   |       3.49 |
| Bird bean bag toy   |       3.49 |
| Rabbit bean bag toy |       3.49 |
| 8 inch teddy bear   |       5.99 |
| 12 inch teddy bear  |       8.99 |
| 18 inch teddy bear  |      11.99 |
| Raggedy Ann         |       4.99 |
+---------------------+------------+
7 rows in set (0.00 sec)

5.1.3 求值顺序

WHERE子句可以包含任意数目的AND和OR操作符,允许两者结合进行复杂、高级的过程。
但是,组合AND和OR会带来一个有趣的问题,为了说明这个问题,举下例:假如需要列出价格为10美元及以上,且由DLL01或BRS01制造的所有产品。

错误示范:

mysql> SELECT prod_name,prod_price
    -> FROM Products
    -> WHERE vend_id = 'DLL01' OR vend_id = 'BRS01' AND prod_price >=10;
+---------------------+------------+
| prod_name           | prod_price |
+---------------------+------------+
| Fish bean bag toy   |       3.49 |
| Bird bean bag toy   |       3.49 |
| Rabbit bean bag toy |       3.49 |
| 18 inch teddy bear  |      11.99 |
| Raggedy Ann         |       4.99 |
+---------------------+------------+
5 rows in set (0.00 sec)

显然,返回的结果有4行价格小于10美元,为什么会这样呢?明明是我先……咳。

问题在于求值的顺序,和大多数语言一样,SQL在处理OR操作符之前,优先处理AND操作符。

因此,需要使用圆括号对操作符进行分组:

mysql> SELECT prod_name,prod_price
    -> FROM Products
    -> WHERE (vend_id = 'DLL01' OR vend_id = 'BRS01') AND prod_price >=10;
+--------------------+------------+
| prod_name          | prod_price |
+--------------------+------------+
| 18 inch teddy bear |      11.99 |
+--------------------+------------+
1 row in set (0.00 sec)

这就对了,以上。

5.2 IN操作符

IN操作符用来指定条件范围,范围中每个条件都可以进行匹配,IN取一组由逗号分隔,并括在圆括号中的合法值,例子如下 :

mysql> SELECT prod_name,prod_price
    -> FROM Products
    -> WHERE vend_id IN('DLL01','BRS01')
    -> ORDER BY prod_name;
+---------------------+------------+
| prod_name           | prod_price |
+---------------------+------------+
| 12 inch teddy bear  |       8.99 |
| 18 inch teddy bear  |      11.99 |
| 8 inch teddy bear   |       5.99 |
| Bird bean bag toy   |       3.49 |
| Fish bean bag toy   |       3.49 |
| Rabbit bean bag toy |       3.49 |
| Raggedy Ann         |       4.99 |
+---------------------+------------+
7 rows in set (0.00 sec)

可以看到,这个IN操作符实际上做到了可以用OR操作符的事情,不过,IN操作符有以下优点:

  • 合法选项较多时IN更直观。
  • 与其他AND和OR组合使用IN时,求值顺序更容易管理。
  • IN操作符比一组OR操作符快得多。
  • IN的最大优点:可以包含其他SELECT语句,可以更动态地建立WHERE子句。

5.3 NOT操作符

WHERE子句中的NOT操作符有且只有一个功能,那就是否定其后跟着的任何条件,由于NOT从不单独使用,而是总与其他操作符仪器使用,所以它的语法和其他操作符有所不同。

NOT关键字可以用在要过滤的列前,而不仅是放在后面。

下面的例子说明NOT的用法,列出除了DLL01之外的所有供应商制造的产品:

mysql> SELECT prod_name
    -> FROM Products
    -> WHERE NOT vend_id = 'DLL01'
    -> ORDER BY prod_name;
+--------------------+
| prod_name          |
+--------------------+
| 12 inch teddy bear |
| 18 inch teddy bear |
| 8 inch teddy bear  |
| King doll          |
| Queen doll         |
+--------------------+
5 rows in set (0.00 sec)

这里,NOT否定了其后的“vent_id=’DLL01’”条件。

第6课 用通配符进行过滤

这一课介绍什么是通配符,如何使用通配符以及怎样使用LIKE操作符进行通配搜索。

6.1 LIKE操作符

前面介绍的所有操作符都是针对已知值进行过滤的,不管是匹配一个值还是多个值,检验大于还是小于已知值,或者检查某个范围的值,共同点是过滤中使用的值都是一致的。但是,并非任何时候这样的过滤方法都是好用的。有时我们需要利用通配符匹配条件查询的值中的一部分字符。

通配符本身实际上是SQL的WHERE子句中有特殊含义的字符,SQL支持几种通配符,而为了使用通配符必须使用LIKE操作符。

6.1.1 百分号(%)通配符

最常使用的通配符是百分号(%),在搜索串中,%表示任何字符出现任意次数。
下例查找出所有以词Fish起头的产品:

mysql> SELECT prod_name
    -> FROM Products
    -> WHERE prod_name LIKE 'Fish%';
+-------------------+
| prod_name         |
+-------------------+
| Fish bean bag toy |
+-------------------+
1 row in set (0.00 sec)

执行上例使用“Fish%”的子句时,检索的是prod_name列任何以Fish起头的词。
%告诉DBMS,接受Fish之后的任意字符,不管有多少、哪些字符。

对于Access,用的是*而不是%。

通配符可以再搜索模式中的任意位置使用,并且可以使用多个通配符,下例使用两个通配符,位于模式的两端:

mysql> SELECT prod_id , prod_name
    -> FROM Products
    -> WHERE prod_name LIKE '%bean bag%';
+---------+---------------------+
| prod_id | prod_name           |
+---------+---------------------+
| BNBG01  | Fish bean bag toy   |
| BNBG02  | Bird bean bag toy   |
| BNBG03  | Rabbit bean bag toy |
+---------+---------------------+
3 rows in set (0.00 sec)

通配符也可以出现在搜索模式的中间,不赘述。

需要注意的是,%不会匹配NULL行。

6.1.2 下划线(_)通配符

下划线的用途与%医院,但它只能匹配单个字符而不是多个:

mysql> SELECT prod_id , prod_name
    -> FROM Products
    -> WHERE prod_name LIKE '__inch teddy bear';
+---------+-------------------+
| prod_id | prod_name         |
+---------+-------------------+
| BR01    | 8 inch teddy bear |
+---------+-------------------+
1 row in set (0.00 sec)

mysql> SELECT prod_id , prod_name
    -> FROM Products
    -> WHERE prod_name LIKE '___inch teddy bear';
+---------+--------------------+
| prod_id | prod_name          |
+---------+--------------------+
| BR02    | 12 inch teddy bear |
| BR03    | 18 inch teddy bear |
+---------+--------------------+
2 rows in set (0.00 sec)

可以看到,每一个下划线占据一个字符位置。
如果使用%的话,则可以返回全部三行:

mysql> SELECT prod_id , prod_name
    -> FROM Products
    -> WHERE prod_name LIKE '%inch teddy bear';
+---------+--------------------+
| prod_id | prod_name          |
+---------+--------------------+
| BR01    | 8 inch teddy bear  |
| BR02    | 12 inch teddy bear |
| BR03    | 18 inch teddy bear |
+---------+--------------------+
3 rows in set (0.00 sec)

6.1.3 方括号([])通配符

方括号([])通配符用来指定一个字符集,它必须匹配指定位置(通配符的位置)的一个字符。需要注意的是,并非所有DBMS都支持这样的集合,只有Access和SQL Server支持。

Mysql中无法使用,故略过此段。

6.2 使用通配符的技巧:

SQL的通配符很有用,但这种功能是有代价的:通常是更久的处理时间。
一些使用通配符的技巧如下:

  • 不要过度使用通配符,其他操作符能达到相同目的的场合,就尽量不用通配符。
  • 在确实需要通配符时,也不要把它们用在搜索模式的开始处:把通配符至于所搜索模式的开始处,搜索起来是最慢的。
  • 注意通配符的位置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值