作者:edelweiss 日期:2020年2月20日
参考书目:ISBN 978-7-115-31398-0 SQL必知必会(第4版)
0. 图书提供的样例表导入数据库
0.1 样例表来源
本书的作者在下面链接为MySQL提供了如下文件
https://forta.com/books/0672336073/
我将 create.txt 和 populate.txt 转换成了.sql格式, 便于在命令行模式导入
链接:https://pan.baidu.com/s/1rXYQzgsrD1Gqxbh4WEDqXw
提取码:tcih
0.2 Linux 用命令行导入
hanhan@Celeron-B815:~/Downloads/sql必知必会/mesql$ mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 31
Server version: 5.7.29-0ubuntu0.18.04.1 (Ubuntu)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
########### 上面的内容 "欢迎光临MySQL" 不用关心#######
在命令行界面连接成功 MySQL 之后, 会看到:
mysql> 在后面直接输入命令,想要这条命令执行写分号;再回车
--是MySQL中注释的标记,所以 “--和后面的文字不要键入”
#####################################################
mysql> show databases; --显示当前数据库管理系统里面管理的全部数据库
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql> create database hello; --创建一个新的数据库 hello
Query OK, 1 row affected (0.04 sec)
mysql> use hello; --使用数据库hello
Database changed
mysql> source ./create.sql --运行脚本 create.sql 在数据库(hello)中创建表
Query OK ...
...
mysql> source ./populate.sql; --运行脚本 populate.sql 给上一步创建的表添加数据
Query OK...
...
./create.sql 前面的./ 在 Linux 下是当前文件目录的意思,我在 ./ 目录下已经放好里我前面提到的两个 .sql 文件,请在这里把 ./ 替换成自己的文件路径。
如果你执行两次脚本后都能看到一大串 Query OK 的提示,那么数据就导入成功了。
记住你当前所在的位置,“MySQL数据库管理系统下面的 hello 数据库中”。 如果你想使用里面的数据练习,得先确定你在 hello 数据库中。
1. 检索数据
1.1 SELECT 语句
使用SELECT 检索表数据,必须至少给出两条信息--想查找什么,从什么地方查找。
1.2 检索单个列
mysql> SELECT Prod_name --检索Prod_name列
-> FROM Products; --从Products表中
+---------------------+
| Prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
| Raggedy Ann |
| King doll |
| Queen doll |
+---------------------+
9 rows in set (0.00 sec)
mysql>
SQL 语句不区分大小写,因此SELECT 与 select 是相同的。许多人习惯 SQL 关键字大写, 而对列名字和表名字使用小写, 这样做使代码更易于阅读和调试。
表明和列名是要区分大小写的。
在处理SQL语句时,其中所有空格都会被忽略。SQL 语句可以写成长长的一行,也可以分写在多行。
1.3 检索多个列
SELECT 检索多个列, 列名之间用逗号分隔。
mysql> SELECT prod_id, prod_name, prod_price
-> FROM Products;
+---------+---------------------+------------+
| prod_id | prod_name | prod_price |
+---------+---------------------+------------+
| BNBG01 | Fish bean bag toy | 3.49 |
| BNBG02 | Bird bean bag toy | 3.49 |
| BNBG03 | Rabbit bean bag toy | 3.49 |
| BR01 | 8 inch teddy bear | 5.99 |
| BR02 | 12 inch teddy bear | 8.99 |
| BR03 | 18 inch teddy bear | 11.99 |
| RGAN01 | Raggedy Ann | 4.99 |
| RYL01 | King doll | 9.49 |
| RYL02 | Queen doll | 9.49 |
+---------+---------------------+------------+
9 rows in set (0.00 sec)
mysql>
1.4 检索所有列
使用 星号 ( * )通配符 配合SELECT。
mysql> SELECT *
-> FROM Products;
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
| prod_id | vend_id | prod_name | prod_price | prod_desc |
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
| BNBG01 | DLL01 | Fish bean bag toy | 3.49 | Fish bean bag toy, complete with bean bag worms with which to feed it |
| BNBG02 | DLL01 | Bird bean bag toy | 3.49 | Bird bean bag toy, eggs are not included |
| BNBG03 | DLL01 | Rabbit bean bag toy | 3.49 | Rabbit bean bag toy, comes with bean bag carrots |
| BR01 | BRS01 | 8 inch teddy bear | 5.99 | 8 inch teddy bear, comes with cap and jacket |
| BR02 | BRS01 | 12 inch teddy bear | 8.99 | 12 inch teddy bear, comes with cap and jacket |
| BR03 | BRS01 | 18 inch teddy bear | 11.99 | 18 inch teddy bear, comes with cap and jacket |
| RGAN01 | DLL01 | Raggedy Ann | 4.99 | 18 inch Raggedy Ann doll |
| RYL01 | FNG01 | King doll | 9.49 | 12 inch king doll with royal garments and crown |
| RYL02 | FNG01 | Queen doll | 9.49 | 12 inch queen doll with royal garments and crown |
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
9 rows in set (0.00 sec)
mysql>
1.5 检索不同的值
使用 DISTINCT 关键字去重复数据。
使用前
mysql> SELECT vend_id
-> FROM Products;
+---------+
| vend_id |
+---------+
| BRS01 |
| BRS01 |
| BRS01 |
| DLL01 |
| DLL01 |
| DLL01 |
| DLL01 |
| FNG01 |
| FNG01 |
+---------+
9 rows in set (0.00 sec)
使用后
mysql> SELECT DISTINCT vend_id
-> FROM Products;
+---------+
| vend_id |
+---------+
| BRS01 |
| DLL01 |
| FNG01 |
+---------+
3 rows in set (0.00 sec)
不能部分使用DISTINCT
DISTINCT 关键字作用于所有的列,不仅是跟在后面的那一列。例如,你指定 :
SELECT DISTINCT vend_id, prod_price FROM Products;
只有vend_id, prod_price 两列内容都相同的行会去重。
先看看这张表的数据
mysql> select *
-> FROM Products;
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
| prod_id | vend_id | prod_name | prod_price | prod_desc |
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
| BNBG01 | DLL01 | Fish bean bag toy | 3.49 | Fish bean bag toy, complete with bean bag worms with which to feed it |
| BNBG02 | DLL01 | Bird bean bag toy | 3.49 | Bird bean bag toy, eggs are not included |
| BNBG03 | DLL01 | Rabbit bean bag toy | 3.49 | Rabbit bean bag toy, comes with bean bag carrots |
| BR01 | BRS01 | 8 inch teddy bear | 5.99 | 8 inch teddy bear, comes with cap and jacket |
| BR02 | BRS01 | 12 inch teddy bear | 8.99 | 12 inch teddy bear, comes with cap and jacket |
| BR03 | BRS01 | 18 inch teddy bear | 11.99 | 18 inch teddy bear, comes with cap and jacket |
| RGAN01 | DLL01 | Raggedy Ann | 4.99 | 18 inch Raggedy Ann doll |
| RYL01 | FNG01 | King doll | 9.49 | 12 inch king doll with royal garments and crown |
| RYL02 | FNG01 | Queen doll | 9.49 | 12 inch queen doll with royal garments and crown |
+---------+---------+---------------------+------------+-----------------------------------------------------------------------+
9 rows in set (0.00 sec)
使用后
mysql> SELECT DISTINCT vend_id, prod_price FROM Products;
+---------+------------+
| vend_id | prod_price |
+---------+------------+
| DLL01 | 3.49 |
| BRS01 | 5.99 |
| BRS01 | 8.99 |
| BRS01 | 11.99 |
| DLL01 | 4.99 |
| FNG01 | 9.49 |
+---------+------------+
6 rows in set (0.00 sec)
1.6 限制结果
SELECT 返回第一行或者一定数据的行。
各种数据库这个功能的命令不相同。
只列出MySQL
LIMIT 5 指示 MySQL 最多返回 5 行数据。
先查看数据
mysql> SELECT prod_name
-> FROM Products;
+---------------------+
| prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
| Raggedy Ann |
| King doll |
| Queen doll |
+---------------------+
9 rows in set (0.00 sec)
使用 LIMIT
mysql> SELECT prod_name
-> FROM Products
-> LIMIT 5;
+---------------------+
| prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
+---------------------+
5 rows in set (0.00 sec)
可以看到从第 1 行开始,一共显示了 5 行数据。
使用 OFFSET
如果想从第 6 行开始,最多显示 2 行数据呢?
-> FROM Products
-> LIMIT 2 OFFSET 5;
+--------------------+
| prod_name |
+--------------------+
| 18 inch teddy bear |
| Raggedy Ann |
+--------------------+
2 rows in set (0.00 sec)
这里的 OFFSET 是偏移量,可以想象一个光标从第 1 行 偏移到了第 2 行 ,只向下移动了一次。
所以在这里,OFFSET 是 5 而不是 6;
1.7 使用注释
在实际工作中 SQL 语句会很长且复杂,如果你想添加一些注释到 SQL 脚本中
行内注释
使用 -- (两个连字符)嵌在行内,之后的文本就是注释。
mysql> SELECT prod_name -- 这是一条行内注释
-> FROM Products;
+---------------------+
| prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
| Raggedy Ann |
| King doll |
| Queen doll |
+---------------------+
9 rows in set (0.00 sec)
mysql>
行注释
在一行的开始处使用#,这一行都将作为注释。
**块注释**
/*和 C 语言块注释相同*/
mysql> # 这是一条行注释
mysql> SELECT prod_name -- 这是一条行内注释
-> FROM Products;
+---------------------+
| prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
| Raggedy Ann |
| King doll |
| Queen doll |
+---------------------+
9 rows in set (0.00 sec)
1.8 小结
如何用 SELECT 检索单列,多列,所有列。
返回的值去重。
从指定的行开始检索自定数量的列。
2. 排序检索数据
2.1 排序数据
SELECT prod_name FROM Products; 能返回一列数据,但是没有特定的顺序。
mysql> SELECT prod_name
-> FROM Products;
+---------------------+
| prod_name |
+---------------------+
| Fish bean bag toy |
| Bird bean bag toy |
| Rabbit bean bag toy |
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
| Raggedy Ann |
| King doll |
| Queen doll |
+---------------------+
9 rows in set (0.00 sec)
其实,检索出的数据并不是随机显示的。如果不排序,数据一般将以它在底层表中出现的顺序显示,有可能是数据添加到表中的顺序。
但是在进行过数据更新和删除后,这个顺序就受数据库管理系统回收存储空间的细节影响了。数据默认检索出来的顺序会很混乱,所以一般假定检索出的数据没有任何的意义。
子句 (clause)
SQL 语句由字句构成, 有些子句是必须的, 有些则是可选的。一个字句通常由一个关键字加上所提供的数据组成。
比如 SELECT 语句 的 FROM 字句。
使用 ORDER BY 子句
在 ORDER BY 子句后面指定列名,检索出来的内容会按照指定列的数据进行排序。
mysql> SELECT prod_name
-> FROM Products
-> ORDER BY prod_name;
+---------------------+
| prod_name |
+---------------------+
| 12 inch teddy bear |
| 18 inch teddy bear |
| 8 inch teddy bear |
| Bird bean bag toy |
| Fish bean bag toy |
| King doll |
| Queen doll |
| Rabbit bean bag toy |
| Raggedy Ann |
+---------------------+
9 rows in set (0.00 sec)
检索的列 和 用来排序的列不要求必须相同, 这里都是用 prod_name 。
ORDER BY 子句要写到一条 SQL 语句的最后面,否则会报错。
2.2 按多个列排序
有这样的一种需求,比如显示员工名单(英文名),希望按照姓的第一个单词排序,同姓的人再按照名字第一个单词排序。
要参照多个列排序,只要直接填入多个列名即可,中间用逗号分开。
检索三个列,并按照其中两个列对结果进行排序 --首先按prod_price (价格)排序,然后按 prod_name (名称)排序。
mysql> SELECT prod_id, prod_price, prod_name
-> FROM Products
-> ORDER BY prod_price, prod_name;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name |
+---------+------------+---------------------+
| BNBG02 | 3.49 | Bird bean bag toy |
| BNBG01 | 3.49 | Fish bean bag toy |
| BNBG03 | 3.49 | Rabbit bean bag toy |
| RGAN01 | 4.99 | Raggedy Ann |
| BR01 | 5.99 | 8 inch teddy bear |
| BR02 | 8.99 | 12 inch teddy bear |
| RYL01 | 9.49 | King doll |
| RYL02 | 9.49 | Queen doll |
| BR03 | 11.99 | 18 inch teddy bear |
+---------+------------+---------------------+
9 rows in set (0.00 sec)
2.3 按列位置排序
除了能直接指定 列名 排序外,ORDER BY 还支持这样一种语法: SELECT 检索的列 从左到右排的 相对位置 编号,可以代替 ORDER BY 子句中的列名 。
mysql> SELECT prod_id, prod_price, prod_name
-> FROM Products
-> ORDER BY 2, 3;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name |
+---------+------------+---------------------+
| BNBG02 | 3.49 | Bird bean bag toy |
| BNBG01 | 3.49 | Fish bean bag toy |
| BNBG03 | 3.49 | Rabbit bean bag toy |
| RGAN01 | 4.99 | Raggedy Ann |
| BR01 | 5.99 | 8 inch teddy bear |
| BR02 | 8.99 | 12 inch teddy bear |
| RYL01 | 9.49 | King doll |
| RYL02 | 9.49 | Queen doll |
| BR03 | 11.99 | 18 inch teddy bear |
+---------+------------+---------------------+
9 rows in set (0.00 sec)
mysql>
这样操作的好处是能少敲几个列名,但是可读性变低了。其次,如果参照排序的列不在 SELECT 检索的列里面,这种语法就没办法使用了。
2.4 指定排序方向
数据排序不限于升序排序 ( 从A到Z), 这只是默认的排序顺序。还可以使用 ORDER BY 子句 配合DESC 关键字进行降序排序。
下面的例子以价格降序来排序产品 (最贵的在前面)
mysql> SELECT prod_id, prod_price, prod_name
-> FROM Products
-> ORDER BY prod_price DESC;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name |
+---------+------------+---------------------+
| BR03 | 11.99 | 18 inch teddy bear |
| RYL01 | 9.49 | King doll |
| RYL02 | 9.49 | Queen doll |
| BR02 | 8.99 | 12 inch teddy bear |
| BR01 | 5.99 | 8 inch teddy bear |
| RGAN01 | 4.99 | Raggedy Ann |
| BNBG01 | 3.49 | Fish bean bag toy |
| BNBG02 | 3.49 | Bird bean bag toy |
| BNBG03 | 3.49 | Rabbit bean bag toy |
+---------+------------+---------------------+
9 rows in set (0.00 sec)
mysql>
单个DESC关键字只能修饰单独的一列
mysql> SELECT prod_id, prod_price, prod_name
-> FROM Products
-> ORDER BY prod_price DESC, prod_name;
+---------+------------+---------------------+
| prod_id | prod_price | prod_name |
+---------+------------+---------------------+
| BR03 | 11.99 | 18 inch teddy bear |
| RYL01 | 9.49 | King doll |
| RYL02 | 9.49 | Queen doll |
| BR02 | 8.99 | 12 inch teddy bear |
| BR01 | 5.99 | 8 inch teddy bear |
| RGAN01 | 4.99 | Raggedy Ann |
| BNBG02 | 3.49 | Bird bean bag toy |
| BNBG01 | 3.49 | Fish bean bag toy |
| BNBG03 | 3.49 | Rabbit bean bag toy |
+---------+------------+---------------------+
9 rows in set (0.00 sec)
mysql>
可以看到 prod_price 列以降序排序,而 prod_name 列(在每个价格内)仍然按标准的升序排序。
如果想在多个列上进行降序排序,必须对每一列指定 DESC 关键字。
2.5 小结
用 SELECT 语句的 ORDER BY 子句对检索出的数据进行排序。这个子句必须是 SELECT 语句中的最后一条子句。根据需要,可以利用它在一个或多个列上对数据进行排序。
3. 过滤数据
3.1 使用 WHERE 子句
使用 SELECT 语句的 WHERE 子句指定搜索满足条件的数据。
在 SELECT 语句中, 数据根据 WHERE 子句中指定的搜索条件进行过滤。 WHERE 子句在表名 (FROM 子句) 之后给出。
这条语句从 products 表中检索两个列,返回其中 prod_price 值为 3.49 的行。
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)
3.2 WHERE 子句操作符
SQL 支持的所有条件操作符
操作符 | 说明 | 操作符 | 说明 |
---|---|---|---|
= | 等于 | > | 大于 |
<> | 不等于 | >= | 大于等于 |
!= | 不等于 | !> | 不大于 |
< | 小于 | BETEEN | 在指定的两个值之间 |
<= | 小于等于 | IS NULL | 为 NULL 值 |
!< | 不小于 |
注意操作符兼容性的问题
<> 和 != 是一个意思,!< 和 >= 是一个意思,但是并非所有的数据库管理系统都同时支持两种操作符。
检查单个值
列出所有价格小于 10 美元的产品。
mysql> SELECT prod_name, prod_price
-> FROM Products
-> WHERE 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 |
| 8 inch teddy bear | 5.99 |
| 12 inch teddy bear | 8.99 |
| Raggedy Ann | 4.99 |
| King doll | 9.49 |
| Queen doll | 9.49 |
+---------------------+------------+
8 rows in set (0.00 sec)
不匹配检查
列出所有 vend_id 不是 DLL01 的 数据。
mysql> SELECT vend_id, prod_name
-> FROM Products
-> WHERE vend_id <> 'DLL01';
+---------+--------------------+
| vend_id | prod_name |
+---------+--------------------+
| BRS01 | 8 inch teddy bear |
| BRS01 | 12 inch teddy bear |
| BRS01 | 18 inch teddy bear |
| FNG01 | King doll |
| FNG01 | Queen doll |
+---------+--------------------+
5 rows in set (0.00 sec)
注意 DLL01 添加了单引号
在 WHERE 子句中的条件如果是字符串,就要用 '单引号' 括起来,如果是数值则不需要。
范围值检查
使用 BETWEEN 操作符进行范围检查,它的语法是这样:
BETWEEN 值1 AND 值2 ,过滤的范围是大于等于 值1,小于等于 值2。
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)
空值检查
有时候表中可能包含空值,(这取决于表的设计)在一个列不含值的时候,称其包含空值 NULL。
有个特殊的子句 IS NULL 专门用来检查是否存在空值,而不是 = NULL。
mysql> SELECT prod_name
-> FROM Products
-> WHERE prod_price IS NULL;
Empty set (0.00 sec)
当前 prod_price 列中没有为 NULL 的行,所以没有数据返回。
找到一张有 NULL 数据的表,试试
mysql> SELECT cust_name
-> FROM Customers
-> WHERE cust_email IS NULL;
+---------------+
| cust_name |
+---------------+
| Kids Place |
| The Toy Store |
+---------------+
2 rows in set (0.00 sec)
mysql> 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>
3.3 小结
用 SELECT 语句 WHERE 子句过滤返回的数据,过滤相等、不相等、大于、小于、值的范围以及 NULL 值等。
4. 高级数据过滤
4.1 组合 WHERE 字句
SQL 允许使用多个 WHERE 子句作为筛选数据的条件,在这里引入 AND (与) 和 OR (或) 操作符。
AND 操作符
全部条件满足的行才会显示出来。
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)
vend_id = 'DLL01' 且同时满足 prod_price <= 4 的行才会显示出来。
OR操作符
只要能满足一个条件的行就会被显示出来。
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)
求值顺序: 运算符优先级
就像其他语言一样 SQL 也有运算符优先级引发的问题, SQL 优先处理 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 |
+---------------------+------------+
| 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)
现在检索出来的是 vend_id = 'BRS01' 且满足 prod_price >= 10的行,和所有vend_id = 'DLL01' 的行。
如果想改变运算顺序,可以用圆括号进行分组
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)
为了提高可读性,建议总是使用圆括号来强调运算顺序
4.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)
SELECT 检索 所有 vend_id 为 DLL01 和 BRS01 的行。
NOT 操作符
WHERE 字句中用来剔除指定数据的关键字。
下面的例子,可以检索出 除了 vend_id = '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)
4.3 小结
如何用 AND 和 OR 操作符组合成的 WHERE 子句, 如何使用 IN 和 NOT 。