读书笔记_SQL必知必会(作者: 福塔)_SQL必知必会书评-查字典图书网
查字典图书网
当前位置: 查字典 > 图书网 > 编程 > SQL必知必会 > 读书笔记_SQL必知必会(作者: 福塔)
吕何甲 SQL必知必会 的书评 发表时间:2010-08-22 21:08:14

读书笔记_SQL必知必会(作者: 福塔)


  注1:该笔记为未完成版(最后修改日期为2009.3.25)
  注2:转帖请注明出处(笔记作者:城市行走者)

第0章 安装mysql以及建库、建表、导入数据
第1章 了解SQL
1.1数据库基础
1.2 什么是SQL
1.3 动手实践
第2章 检索数据
2.1 SELECT 语句
2.2 检索单个列
2.3 检索多个列
2.4 检索所有列
第3章 排序检索数据
3.1 排序数据
3.2 按多个列排序
3.3 按列位置排序
3.4 指定排序方向
第4章 过滤数据
4.1 使用WHERE子句
4.2 WHERE子句操作符
4.2.1 检查单个值
4.2.2 不匹配检查
4.2.3 范围值检查
4.2.4 空值检查
第 5 章 高级数据过滤
5.1 组合WHERE子句
5.1.1 AND操作符 (与运算)
5.1.2 OR操作符 (或运算)
5.1.3 计算次序(操作符的优先级)
5.2 IN操作符
5.3 NOT操作符
第6章 用通配符进行过滤
6.1 LIKE操作符
6.1.1 百分号(%)通配符
6.1.2 下划线(_)通配符
6.1.3 方括号([])通配符
6.2 使用通配符的技巧
附录:MySQL正则表达式
第7章 创建计算字段
7.1 计算字段
7.2 拼接字段
7.3 执行算术计算
第8章 使用数据处理函数
8.1 函数
8.2 使用函数
8.2.1 文本处理函数
8.2.2 日期和时间处理函数
8.2.3 数值处理函数
第9章 汇总数据
9.1 聚集函数
9.2 聚集不同值
9.3 组合聚集函数
第10章 分组数据
10.1 数据分组
10.2 创建分组
10.3 过滤分组
10.4 分组和排序
10.5 SELECT子句顺序
第11章 使用子查询
11.1 子查询
11.2 利用子查询进行过滤
11.3 作为计算字段使用子查询
第12章 联结表(join table)
12.1 联结
12.1.1 关系表
12.2 创建联结
12.2.2 内部联结
12.2.3 联结多个表
第13章 创建高级联结
13.1 使用表别名
13.2 使用不同类型的联结
13.2.1 自联结
13.2.2 自然联结
13.2.3 外部联结
13.3 使用带聚集函数的联结
13.4 使用联结和联结条件
第14章 组合查询
14.1 组合查询
14.2 创建组合查询
14.2.1 使用UNION
14.2.2 UNION规则
14.2.3 包含或取消重复的行
14.2.4 对组合查询排序
第15章 插入数据
15.1 插入数据
15.1.1 插入完整的行
15.1.2 插入部分行
15.1.3 插入检索出的数据
15.2 从一个表复制到另一个表
第16章 更新和删除数据
16.1 更新数据
16.2 删除数据
16.3 更新和删除的指导原则
第17章 创建和操纵表
17.1 创建表
17.1.1 表创建基础
17.1.2 使用NULL值
17.1.3 制定默认值
17.2 更新表结构
17.3 删除表
17.4 重命名表名
第18章 使用视图
18.1 视图
18.1.1 为什使用视图
18.1.2 视图的规则和限制
18.2 创建视图
18.2.1 利用视图简化复杂的联结
18.2.2 用视图重新格式化检索出的数据
18.2.3 用视图过滤不想要的数据
18.2.4 使用视图与计算字段
18.3 小结
第19章 使用存储过程
附录: Oracle 和 mysql 的一些简单SQL操作命令对比
 
第0章 安装mysql以及建库、建表、导入数据
安装mysql时,向导建立的管理员用户和密码
root:lvhejia001;'

    一、连接mysql。

    1、首先在打开DOS窗口,再键入命令mysql -uroot -p, 回车后提示你输密码。
2、直接利用开始菜单!开始----程序---mysql5.0

二、建库、建表、导入数据
1、 显示数据库列表。
例子:
mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| customers |
| orderitems |
| orders |
| products |
| vendors |
+-------------------+
5 rows in set (0.00 sec)
刚开始时才两个数据库:mysql和test。 mysql库很重要它里面有mysql的系统信息,
我们改密码和新增用户,实际上就是用这个库进行操作。

2、 显示库中的数据表:
语法:use 数据库名; //打开库,学过FOXBASE的一定不会陌生吧
     show 表名;

3、 显示数据表的结构:
语法:describe 表名;

4、 建库:
语法:create database 库名;

例子:
mysql> create database example;
Query OK, 1 row affected (0.00 sec)

mysql> use example;
Database changed

mysql> show tables;
Empty set (0.00 sec)



5、 建表:
语法:use 库名;
      create table 表名(字段设定列表);
        
使用Ben Forta提供的例子,直接复制粘贴。
-------------------------
-- Create Customers table
-------------------------
CREATE TABLE Customers
(
  cust_id char(10) NOT NULL ,
  cust_name char(50) NOT NULL ,
  cust_address char(50) NULL ,
  cust_city char(50) NULL ,
  cust_state char(5) NULL ,
  cust_zip char(10) NULL ,
  cust_country char(50) NULL ,
  cust_contact char(50) NULL ,
  cust_email char(255) NULL
);
……
无错误提示,再检查一下
mysql> show tables;
+-------------------+
| Tables_in_example |
+-------------------+
| customers |
| orderitems |
| orders |
| products |
| vendors |
+-------------------+
5 rows in set (0.00 sec)

6、导入数据
还是使用Ben Forta提供的例子,直接复制粘贴。
---------------------------
-- Populate Customers table
---------------------------
INSERT INTO Customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES('1000000001', 'Village Toys', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'John Smith', 'sales@villagetoys.com');
…… ……

无错误提示
第1章 了解SQL
1.1数据库基础
1.1.1 数据库(database):保存有组织的数据的仓库(数据集合)。
1.1.2 表(table):一种结构化的文件。
1.1.3 列(column):表中的一个字段(field)。
数据类型(data type):每列都有相应的数据类型,它限制或容许该列中存储的数据。
注意:虽然大多数的数据类型得到一致的支持,但许多更为高级的数据类型却不是这样。更糟的是,我们偶热会发现相同的数据类型在不同的DBMS中具有不同的名称。对此用户毫无办法,重要的是在创建表结构时要记住这些差异。
1.1.4 行(row):表中的一个记录(record)。
1.1.5 主键(primary key):一列(或一组列),其值能够唯一标识表中的每一列。
作为主键的列,需要满足以下条件:
1、任意两行都不具有相同的主键值;
2、每一行都必须具有一个主键值(主键列不允许NULL值);
3、主键列中的值不允许修改或更新;
4、主键值不能重用(如果某行从表中删除,它的主键不能赋给以后的新行)

1.2 什么是SQL
SQL(Structured Query Language):结构化查询语言,是一种专门用来与数据库通信的语言。
注意:标准SQL有ANSI标准委员会管理,从而成为ANSI SQL。各个DBMS供应商通过增加语句或指令,对标准SQL进行扩展。

1.3 动手实践
这里使用的DBMS为MySQL。
第2章 检索数据
2.1 SELECT 语句
关键字(keyword):作为SQL组成部分的保留字。
附录E ——SQL保留字(略)

2.2 检索单个列
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.20 sec)

注意:1、SQL语句可以分行。
  2、多条SQL语句必须以分号(;)分隔。
  3、SQL语句不区分大小写。

2.3 检索多个列
列名之间必须以逗号分隔。
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)

2.4 检索所有列
通配符——星号(*)
mysql> select *
    -> from products;
第3章 排序检索数据
3.1 排序数据
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.16 sec)

注意:order by子句必须是select语句中的最后一条子句。

3.2 按多个列排序

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)

3.3 按列位置排序
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)

3.4 指定排序方向
排序时默认为升序ASC(ASDENDING),如果需要降序,则通过关键字DESC(DESCENDING)。
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)

注意:DESC关键字之应用到直接位于其前面的列名。如果想对多个列进行排序,必须对每个列指定DESC关键字。
第4章 过滤数据
4.1 使用WHERE子句
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)

4.2 WHERE子句操作符

操作符 说明
=
!=
<>
<
<=
>
>=
BETWEEN
IS UNLL

4.2.1 检查单个值
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)
4.2.2 不匹配检查
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)

注意:!=和<>通常可以互换。但是,并非所有的DBMS都支持这两种操作符。例如Microsoft Access支持<>而不支持!=。如有疑问,请参阅相应的DBMS文档。
4.2.3 范围值检查
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)
4.2.4 空值检查
mysql> select vend_name, vend_state
    -> from vendors
    -> where vend_state is null;

+----------------+------------+
| vend_name | vend_state |
+----------------+------------+
| Fun and Games | NULL |
| Jouets et ours | NULL |
+----------------+------------+
2 rows in set (0.00 sec)
第 5 章 高级数据过滤
5.1 组合WHERE子句
操作符(operateor):用来联接或改变WHERE子句中的子句的关键词。也称逻辑操作符(logical operator)。
5.1.1 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)
5.1.2 OR操作符 (或运算)
mysql> select vend_id, prod_name, prod_price
    -> from products
    -> where vend_id = 'DLL01' or vend_id = 'BRS01';
+---------+---------------------+------------+
| vend_id | prod_name | prod_price |
+---------+---------------------+------------+
| DLL01 | Fish bean bag toy | 3.49 |
| DLL01 | Bird bean bag toy | 3.49 |
| DLL01 | Rabbit bean bag toy | 3.49 |
| BRS01 | 8 inch teddy bear | 5.99 |
| BRS01 | 12 inch teddy bear | 8.99 |
| BRS01 | 18 inch teddy bear | 11.99 |
| DLL01 | Raggedy Ann | 4.99 |
+---------+---------------------+------------+

注意:事实上,许多DBMS在OR子句的第一个条件满足的情况下,不再计算第二个条件(即,第一个条件满足时,不管第二个条件是否满足,相应的行都将被检索出来)。
5.1.3 计算次序(操作符的优先级)
以下列表显示了操作符优先级的由低到高的顺序。排列在同一行的操作符具有相同的优先级。

:=
||, OR, XOR
&&, AND
NOT
BETWEEN, CASE, WHEN, THEN, ELSE
=, <=>, >=, >, <=, <, <>, !=, IS, LIKE, REGEXP, IN
|
&
<<, >>
-, +
*, /, DIV, %, MOD
^
- (一元减号), ~ (一元比特反转)
!
BINARY, COLLATE

注意:不要过分依赖默认的优先级。任何时候使用具有AND和OR的操作符的WHERE子句时,都应该使用圆括号明确的分组操作符。使用圆括号没有什么坏处,它能消除歧义。
5.2 IN操作符
mysql> select vend_id, prod_name, prod_price
    -> from products
    -> where vend_id = 'DLL01' or vend_id = 'BRS01';

+---------+---------------------+------------+
| vend_id | prod_name | prod_price |
+---------+---------------------+------------+
| DLL01 | Fish bean bag toy | 3.49 |
| DLL01 | Bird bean bag toy | 3.49 |
| DLL01 | Rabbit bean bag toy | 3.49 |
| BRS01 | 8 inch teddy bear | 5.99 |
| BRS01 | 12 inch teddy bear | 8.99 |
| BRS01 | 18 inch teddy bear | 11.99 |
| DLL01 | Raggedy Ann | 4.99 |
+---------+---------------------+------------+
7 rows in set (0.00 sec)

注意:IN操作符可以完成OR操作符完全相同的功能。

IN操作符最大的优点是可以包含其他SELECT语句,使得能够更动态的建立WHERE子句。详细介绍在第11章。
5.3 NOT操作符
mysql> select vend_id, prod_name, prod_price
    -> from products
    -> where not vend_id = 'DLL01' ;

+---------+--------------------+------------+
| vend_id | prod_name | prod_price |
+---------+--------------------+------------+
| BRS01 | 8 inch teddy bear | 5.99 |
| BRS01 | 12 inch teddy bear | 8.99 |
| BRS01 | 18 inch teddy bear | 11.99 |
| FNG01 | King doll | 9.49 |
| FNG01 | Queen doll | 9.49 |
+---------+--------------------+------------+
5 rows in set (0.00 sec)

注意:NOT操作符在复杂子句中用处更大,比如与IN操作符联合使用——NOT IN。
第6章 用通配符进行过滤
6.1 LIKE操作符
通配符(wildcard):用来匹配值(文本字段,即“串”)的一部分的特殊字符。
搜索模式(search pattern):由字面值、通配符或者两者组合构成的搜索条件。
6.1.1 百分号(%)通配符
百分号(%)表示任何字符出现任意次数。
mysql> select prod_name
    -> from products
    -> where prod_name like 'fish%';

+-------------------+
| prod_name |
+-------------------+
| Fish bean bag toy |
+-------------------+
1 row in set (0.01 sec)

注意:根据DBMS的不同及其配置,搜索可以是区分大小写的!

mysql> select prod_name
    -> from products
    -> where prod_name like 'f%y';

+-------------------+
| prod_name |
+-------------------+
| Fish bean bag toy |
+-------------------+
1 row in set (0.00 sec)
注意:要特别小心后面所跟的空格。许多DBMS,包括Microsoft Access,都用空格来填补字段内容。
6.1.2 下划线(_)通配符
下划线(_)表示任意单个字符。
mysql> select prod_name
    -> from products
    -> where prod_name like '_ inch teddy bear';

+-------------------+
| prod_name |
+-------------------+
| 8 inch teddy bear |
+-------------------+
1 row in set (0.00 sec)

mysql> select prod_name
    -> from products
    -> where prod_name like '% inch teddy bear';

+--------------------+
| prod_name |
+--------------------+
| 8 inch teddy bear |
| 12 inch teddy bear |
| 18 inch teddy bear |
+--------------------+
3 rows in set (0.00 sec)
6.1.3 方括号([])通配符
方括号([])通配符:用来指定一个字符集。
注意:并不是所有的SBMS都支持方括号([])通配符
6.2 使用通配符的技巧
除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。


附录:MySQL正则表达式
 
正则表达式是为复杂搜索指定模式的强大方式。
MySQL采用Henry Spencer的正则表达式实施,其目标是符合POSIX 1003.2。请参见附录C:感谢。MySQL采用了扩展的版本,以支持在SQL语句中与REGEXP操作符一起使用的模式匹配操作。请参见3.3.4.7节,“模式匹配”。
在本附录中,归纳了在MySQL中可用于REGEXP操作的特殊字符和结构,并给出了一些示例。本附录未包含可在Henry Spencer的regex(7)手册页面中发现的所有细节。该手册页面包含在MySQL源码分发版中,位于regex目录下的regex.7文件中。
正则表达式描述了一组字符串。最简单的正则表达式是不含任何特殊字符的正则表达式。例如,正则表达式hello匹配hello。
非平凡的正则表达式采用了特殊的特定结构,从而使得它们能够与1个以上的字符串匹配。例如,正则表达式hello|word匹配字符串hello或字符串word。
作为一个更为复杂的示例,正则表达式B[an]*s匹配下述字符串中的任何一个:Bananas,Baaaaas,Bs,以及以B开始、以s结束、并在其中包含任意数目a或n字符的任何其他字符串。
对于REGEXP操作符,正则表达式可以使用任何下述特殊字符和结构:
• ^
匹配字符串的开始部分。
mysql> SELECT 'fonfo' REGEXP '^fo$'; -> 0
mysql> SELECT 'fofo' REGEXP '^fo'; -> 1
• $
匹配字符串的结束部分。
mysql> SELECT 'fono' REGEXP '^fono$'; -> 1
mysql> SELECT 'fono' REGEXP '^fo$'; -> 0
• .
匹配任何字符(包括回车和新行)。
mysql> SELECT 'fofo' REGEXP '^f.*$'; -> 1
mysql> SELECT 'fornfo' REGEXP '^f.*$'; -> 1
• a*
匹配0或多个a字符的任何序列。
mysql> SELECT 'Ban' REGEXP '^Ba*n'; -> 1
mysql> SELECT 'Baaan' REGEXP '^Ba*n'; -> 1
mysql> SELECT 'Bn' REGEXP '^Ba*n'; -> 1
• a+
匹配1个或多个a字符的任何序列。
mysql> SELECT 'Ban' REGEXP '^Ba+n'; -> 1
mysql> SELECT 'Bn' REGEXP '^Ba+n'; -> 0
• a?
匹配0个或1个a字符。
mysql> SELECT 'Bn' REGEXP '^Ba?n'; -> 1
mysql> SELECT 'Ban' REGEXP '^Ba?n'; -> 1
mysql> SELECT 'Baan' REGEXP '^Ba?n'; -> 0
• de|abc
匹配序列de或abc。
mysql> SELECT 'pi' REGEXP 'pi|apa'; -> 1
mysql> SELECT 'axe' REGEXP 'pi|apa'; -> 0
mysql> SELECT 'apa' REGEXP 'pi|apa'; -> 1
mysql> SELECT 'apa' REGEXP '^(pi|apa)$'; -> 1
mysql> SELECT 'pi' REGEXP '^(pi|apa)$'; -> 1
mysql> SELECT 'pix' REGEXP '^(pi|apa)$'; -> 0
• (abc)*
匹配序列abc的0个或多个实例。
mysql> SELECT 'pi' REGEXP '^(pi)*$'; -> 1
mysql> SELECT 'pip' REGEXP '^(pi)*$'; -> 0
mysql> SELECT 'pipi' REGEXP '^(pi)*$'; -> 1
• {1}, {2,3}
{n}或{m,n}符号提供了编写正则表达式的更通用方式,能够匹配模式的很多前述原子(或“部分”)。m和n均为整数。
o a*
可被写入为a{0,}。
o a+
可被写入为a{1,}。
o a?
可被写入为a{0,1}。
更准确地讲,a{n}与a的n个实例准确匹配。a{n,}匹配a的n个或更多实例。a{m,n}匹配a的m~n个实例,包含m和n。
m和n必须位于0~RE_DUP_MAX(默认为255)的范围内,包含0和RE_DUP_MAX。如果同时给定了m和n,m必须小于或等于n。
mysql> SELECT 'abcde' REGEXP 'a[bcd]{2}e'; -> 0
mysql> SELECT 'abcde' REGEXP 'a[bcd]{3}e'; -> 1
mysql> SELECT 'abcde' REGEXP 'a[bcd]{1,10}e'; -> 1
• [a-dX], [^a-dX]
匹配任何是(或不是,如果使用^的话)a、b、c、d或X的字符。两个其他字符之间的“-”字符构成一个范围,与从第1个字符开始到第2个字符之间的所有字符匹配。例如,[0-9]匹配任何十进制数字 。要想包含文字字符“]”,它必须紧跟在开括号“[”之后。要想包含文字字符“-”,它必须首先或最后写入。对于[]对内未定义任何特殊含义的任何字符,仅与其本身匹配。
mysql> SELECT 'aXbc' REGEXP '[a-dXYZ]'; -> 1
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]$'; -> 0
mysql> SELECT 'aXbc' REGEXP '^[a-dXYZ]+$'; -> 1
mysql> SELECT 'aXbc' REGEXP '^[^a-dXYZ]+$'; -> 0
mysql> SELECT 'gheis' REGEXP '^[^a-dXYZ]+$'; -> 1
mysql> SELECT 'gheisa' REGEXP '^[^a-dXYZ]+$'; -> 0
• [.characters.]
在括号表达式中(使用[和]),匹配用于校对元素的字符序列。字符为单个字符或诸如新行等字符名。在文件regexp/cname.h中,可找到字符名称的完整列表。
mysql> SELECT '~' REGEXP '[[.~.]'; -> 1
mysql> SELECT '~' REGEXP '[[.tilde.]'; -> 1
• [=character_class=]
在括号表达式中(使用[和]),[=character_class=]表示等同类。它与具有相同校对值的所有字符匹配,包括它本身,例如,如果o和(+)均是等同类的成员,那么[[=o=]、[[=(+)=]和[o(+)]是同义词。等同类不得用作范围的端点。
• [:character_class:]
在括号表达式中(使用[和]),[:character_class:]表示与术语类的所有字符匹配的字符类。标准的类名称是:
alnum 文字数字字符
alpha 文字字符
blank 空白字符
cntrl 控制字符
digit 数字字符
graph 图形字符
lower 小写文字字符
print 图形或空格字符
punct 标点字符
space 空格、制表符、新行、和回车
upper 大写文字字符
xdigit 十六进制数字字符
它们代表在ctype(3)手册页面中定义的字符类。特定地区可能会提供其他类名。字符类不得用作范围的端点。
mysql> SELECT 'justalnums' REGEXP '[[:alnum:]+'; -> 1
mysql> SELECT '!!' REGEXP '[[:alnum:]+'; -> 0
• [[:<:], [[:>:]
这些标记表示word边界。它们分别与word的开始和结束匹配。word是一系列字字符,其前面和后面均没有字字符。字字符是alnum类中的字母数字字符或下划线(_)。
mysql> SELECT 'a word a' REGEXP '[[:<:]word[[:>:]'; -> 1
mysql> SELECT 'a xword a' REGEXP '[[:<:]word[[:>:]'; -> 0
要想在正则表达式中使用特殊字符的文字实例,应在其前面加上2个反斜杠“”字符。MySQL解析程序负责解释其中一个,正则表达式库负责解释另一个。例如,要想与包含特殊字符“+”的字符串“1+2”匹配,在下面的正则表达式中,只有最后一个是正确的:
mysql> SELECT '1+2' REGEXP '1+2'; -> 0
mysql> SELECT '1+2' REGEXP '1+2'; -> 0
mysql> SELECT '1+2' REGEXP '1\+2'; -> 1

这是MySQL参考手册的翻译版本,关于MySQL参考手册,请访问dev.mysql.com。原始参考手册为英文版,与英文版参考手册相比,本翻译版可能不是最新的。

第7章 创建计算字段
7.1 计算字段
计算字段并不是实际存在出数据库中。计算字段是运行时在SELECT语句中创建的。
字段(field)与列(column):数据库中一般称为列(column),而术语字段(field)通常用在计算字段的连接上。
7.2 拼接字段
拼接(concatenate):将值联接到一起构成单个值。操作符根据不同的DBMS而有差异。
Oracle、DB2、Sybase使用||。
SQL Server和Sybase使用加号(+)。
MySQL使用CONCAT函数(拼接函数concatenate)。

mysql> select CONCAT(vend_name ,' (',vend_country,')')
    -> from vendors;

+------------------------------------------+
| concat(vend_name ,' (',vend_country,')') |
+------------------------------------------+
| Bear Emporium (USA) |
| Bears R Us (USA) |
| Doll House Inc. (USA) |
| Fun and Games (England) |
| Furball Inc. (USA) |
| Jouets et ours (France) |
+------------------------------------------+
6 rows in set (0.00 sec)

TRIM函数:去掉空格(略)

使用别名,关键词为AS(也可省略)。
mysql> select concat(vend_name ,' (',vend_country,')') AS vend_title
    -> from vendors;
+-------------------------+
| vend_title |
+-------------------------+
| Bear Emporium (USA) |
| Bears R Us (USA) |
| Doll House Inc. (USA) |
| Fun and Games (England) |
| Furball Inc. (USA) |
| Jouets et ours (France) |
+-------------------------+
6 rows in set (0.00 sec)

mysql> select concat(vend_name ,' (',vend_country,')') vend_title
    -> from vendors;
+-------------------------+
| vend_title |
+-------------------------+
| Bear Emporium (USA) |
| Bears R Us (USA) |
| Doll House Inc. (USA) |
| Fun and Games (England) |
| Furball Inc. (USA) |
| Jouets et ours (France) |
+-------------------------+
6 rows in set (0.00 sec)

注意:别名一般是一个单词(可用下划线连接多个单词组成)。
7.3 执行算术计算
SQL算术操作符
+
-
*
/


第8章 使用数据处理函数
8.1 函数
与几乎所有的DBMS都同等地支持SQL语句不同,每一个DBMS都有特定的函数。
所以,SQL函数是不可移植的。
可移植(portable):所编写的代码可以在多个系统上运行。

注意:是否应该使用函数?如果你决定使用函数,应该保证做好代码注释,以便以后你(或者其他人)能确切的知道所编写SQL代码的含义。
8.2 使用函数
8.2.1 文本处理函数
函数 说明
LEFT( )
LENGTH( )
LOWER( )
LTRIM( )
RTRIM( )
RIGHT( )
SOUNDEX( ) 语音匹配
UPPER( )

mysql> select upper( vend_name)
    -> from vendors;
+-------------------+
| upper( vend_name) |
+-------------------+
| BEAR EMPORIUM |
| BEARS R US |
| DOLL HOUSE INC. |
| FUN AND GAMES |
| FURBALL INC. |
| JOUETS ET OURS |
+-------------------+
6 rows in set (0.00 sec)
8.2.2 日期和时间处理函数
        Oracle mysql
日期函数 SQL> select sysdate from dual; mysql> select now();
mysql> select sysdate();
mysql> select curdate();
mysql> select current_date;
mysql> select curtime();
mysql> select current_time;
日期格式化 SQL> select to_char(sysdate,'yyyy-mm-dd') from dual;
SQL> select to_char(sysdate,'hh24-mi-ss') from dual; mysql> select date_format(now(),'%Y-%m-%d');
mysql> select time_format(now(),'%H-%i-%S');

mysql> select order_date
    -> from orders;
+---------------------+
| order_date |
+---------------------+
| 2004-05-01 00:00:00 |
| 2004-01-12 00:00:00 |
| 2004-01-30 00:00:00 |
| 2004-02-03 00:00:00 |
| 2004-02-08 00:00:00 |
+---------------------+
5 rows in set (0.00 sec)

mysql> select order_date
    -> from orders
    -> where month(order_date) = 02;
+---------------------+
| order_date |
+---------------------+
| 2004-02-03 00:00:00 |
| 2004-02-08 00:00:00 |
+---------------------+
2 rows in set (0.00 sec)

mysql> select order_date
    -> from orders
    -> where date_format(order_date, '%m') = 02;
+---------------------+
| order_date |
+---------------------+
| 2004-02-03 00:00:00 |
| 2004-02-08 00:00:00 |
+---------------------+
2 rows in set (0.00 sec)
8.2.3 数值处理函数
在主要DBMS函数中,数值函数的统一性最高。
函数 说明
ABS( ) 绝对值
COS( )
EXP( ) 指数值
PI( ) 圆周率
SIN( )
SQRT( ) 平方根
TAN( )

第9章 汇总数据
9.1 聚集函数
聚集函数(aggregate function):从多个输入行中计算,并返回单个值的函数。

SQL聚集函数
AVG( )
COUNT( )
MAX( )
MIN( )
SUM( )

COUNT( )函数有两种使用方式:
1、使用COUNT(*)对表中行的数据进行计数,不管表的列中包含的是空值(NULL)还是非空值。
2、使用COUNT(column)对特定列中具有值的行进行计数,忽略空值(NULL)。
9.2 聚集不同值
DISTINCT参数:只包含不同的值。
9.3 组合聚集函数
(略)
第10章 分组数据
10.1 数据分组
分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算。
10.2 创建分组
分组在SELECT语句的GROUP BY子句中创建。
mysql> select vend_id, count(*) num_prods
    -> from products
    -> group by vend_id;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01 | 3 |
| DLL01 | 4 |
| FNG01 | 2 |
+---------+-----------+
3 rows in set (0.00 sec)

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 vend_id
    -> from products
    -> group by vend_id;
+---------+
| vend_id |
+---------+
| BRS01 |
| DLL01 |
| FNG01 |
+---------+
3 rows in set (0.00 sec)

注意:除聚集语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。
下面是一个反例:
mysql> select prod_name, count(*) num_prods
    -> from products
    -> group by vend_id;
+-------------------+-----------+
| prod_name | num_prods |
+-------------------+-----------+
| 8 inch teddy bear | 3 |
| Fish bean bag toy | 4 |
| King doll | 2 |
+-------------------+-----------+
3 rows in set (0.00 sec)
输出结果没有意义。

mysql> select vend_id, prod_name
    -> from products;
+---------+---------------------+
| vend_id | prod_name |
+---------+---------------------+
| DLL01 | Fish bean bag toy |
| DLL01 | Bird bean bag toy |
| DLL01 | Rabbit bean bag toy |
| BRS01 | 8 inch teddy bear |
| BRS01 | 12 inch teddy bear |
| BRS01 | 18 inch teddy bear |
| DLL01 | Raggedy Ann |
| FNG01 | King doll |
| FNG01 | Queen doll |
+---------+---------------------+
9 rows in set (0.00 sec)
10.3 过滤分组
WHERE过滤行,而HAVING过滤分组。
HAVING支持所有的WHERE操作符。
注意:HAVING和WHERE的差别,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。也就是说,WHERE排出的行不包括在分组中。
mysql> select vend_id, count(*) num_prods
    -> from products
    -> group by vend_id
    -> having count(*) >= 3;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01 | 3 |
| DLL01 | 4 |
+---------+-----------+
2 rows in set (0.00 sec)

HAVING和WHERE同时出现:
mysql> select vend_id, count(*) num_prods
    -> from products
    -> where prod_price >=4
    -> group by vend_id
    -> having count(*) >=2;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01 | 3 |
| FNG01 | 2 |
+---------+-----------+
2 rows in set (0.00 sec)

mysql> select vend_id, count(*) num_prods
    -> from products
    -> group by vend_id;
+---------+-----------+
| vend_id | num_prods |
+---------+-----------+
| BRS01 | 3 |
| DLL01 | 4 |
| FNG01 | 2 |
+---------+-----------+
3 rows in set (0.00 sec)
10.4 分组和排序
GROUP BY的输出可能排序,也可能不排序。保证数据正确排序的方法是使用ORDER BY子句。
10.5 SELECT子句顺序
SELECT
FROM
WHERE
GROUP BY
HAVING
ORDER BY
第11章 使用子查询
11.1 子查询
查询(query):任何SQL语句都是查询。但此术语一般指SELECT语句。
子查询(subquery):嵌套在其他查询中的查询。
11.2 利用子查询进行过滤
格式化SQL:可以把子查询分解为多行,并适当的进行缩进。

注意:作为子查询的SELECT语句只能查询(返回)单个列。企图检索多个列将返回错误。
(例子略)
11.3 作为计算字段使用子查询
(例子略)
第12章 联结表(join table)
12.1 联结
联结(join):join常见不规范译法还有“联接”、“连接”。
12.1.1 关系表
理解关系表的最好方法是来看一个现实世界中的例子。
作者写得非常好,是我见过的最通俗易懂的!中文暂时略
英文如下:
The best way to understand relational tables is to look at a real-world example.
Suppose you had a database table containing a product catalog, with each catalog item in its own row. The kind of information you would store with each item would include a product description and price, along with vendor information about the company that creates the product.
Now suppose that you had multiple catalog items created by the same vendor. Where would you store the vendor information (things like vendor name, address, and contact information)? You wouldn't want to store that data along with the products for several reasons:
Because the vendor information is the same for each product that vendor produces, repeating the information for each product is a waste of time and storage space.
If vendor information changes (for example, if the vendor moves or his area code changes), you would need to update every occurrence of the vendor information.
When data is repeated (that is, the vendor information is used with each product), there is a high likelihood that the data will not be entered exactly the same way each time. Inconsistent data is extremely difficult to use in reporting.
The key here is that having multiple occurrences of the same data is never a good thing, and that principle is the basis for relational database design. Relational tables are designed so that information is split into multiple tables, one for each data type. The tables are related to each other through common values (and thus the relational in relational design).
In our example, you can create two tables, one for vendor information and one for product information. The Vendors table contains all the vendor information, one table row per vendor, along with a unique identifier for each vendor. This value, called a primary key, can be a vendor ID, or any other unique value.
The Products table stores only product information, and no vendor specific information other than the vendor ID (the Vendors table's primary key). This key relates the Vendors table to the Products table, and using this vendor ID enables you to use the Vendors table to find the details about the appropriate vendor.
What does this do for you? Well, consider the following:
Vendor information is never repeated, and so time and space are not wasted.
If vendor information changes, you can update a single record, the one in the Vendors table. Data in related tables does not change.
As no data is repeated, the data used is obviously consistent, making data reporting and manipulation much simpler.
The bottom line is that relational data can be stored efficiently and manipulated easily. Because of this, relational databases scale far better than nonrelational databases.
 
Scale Able to handle an increasing load without failing. A well-designed database or application is said to scale well.


Why Use Joins?
As just explained, breaking data into multiple tables enables more efficient storage, easier manipulation, and greater scalability. But these benefits come with a price.
If data is stored in multiple tables, how can you retrieve that data with a single SELECT statement?
The answer is to use a join. Simply put, a join is a mechanism used to associate tables within a SELECT statement (and thus the name join). Using a special syntax, multiple tables can be joined so that a single set of output is returned, and the join associates the correct rows in each table on-the-fly.
 
Using Interactive DBMS Tools It is important to understand that a join is not a physical entity—in other words, it does not exist in the actual database tables. A join is created by the DBMS as needed, and it persists for the duration of the query execution.
Many DBMSs provide graphical interfaces that can be used to define table relationships interactively. These tools can be invaluable in helping to maintain referential integrity. When using relational tables, it is important that only valid data is inserted into relational columns. Going back to the example, if an invalid vendor ID is stored in the Products table, those products would be inaccessible because they would not be related to any vendor. To prevent this from occurring, the database can be instructed to only allow valid values (ones present in the Vendors table) in the vendor ID column in the Products table. Referential integrity means that the DBMS enforces data integrity rules. And these rules are often managed through DBMS provided interfaces.

12.2 创建联结
mysql> select vend_name, prod_name, prod_price
    -> from vendors, products
    -> where vendors.vend_id = products.vend_id;
+-----------------+---------------------+------------+
| vend_name | prod_name | prod_price |
+-----------------+---------------------+------------+
| Bears R Us | 8 inch teddy bear | 5.99 |
| Bears R Us | 12 inch teddy bear | 8.99 |
| Bears R Us | 18 inch teddy bear | 11.99 |
| Doll House Inc. | Fish bean bag toy | 3.49 |
| Doll House Inc. | Bird bean bag toy | 3.49 |
| Doll House Inc. | Rabbit bean bag toy | 3.49 |
| Doll House Inc. | Raggedy Ann | 4.99 |
| Fun and Games | King doll | 9.49 |
| Fun and Games | Queen doll | 9.49 |
+-----------------+---------------------+------------+
9 rows in set (0.03 sec)

笛卡尔积(cartesian product):由没有连接条件的表关系返回的结果为笛卡尔积。检索出的行数是第一个表的行数乘以第二个表的行数。
为了理解这一点,请看没有连接条件的SELECT语句及输出。
mysql> select vend_name, prod_name, prod_price
    -> from vendors, products;
+-----------------+---------------------+------------+
| vend_name | prod_name | prod_price |
+-----------------+---------------------+------------+
| Bear Emporium | Fish bean bag toy | 3.49 |
| Bears R Us | Fish bean bag toy | 3.49 |
| Doll House Inc. | Fish bean bag toy | 3.49 |
| Fun and Games | Fish bean bag toy | 3.49 |
| Furball Inc. | Fish bean bag toy | 3.49 |
| Jouets et ours | Fish bean bag toy | 3.49 |
| Bear Emporium | Bird bean bag toy | 3.49 |
| Bears R Us | Bird bean bag toy | 3.49 |
| Doll House Inc. | Bird bean bag toy | 3.49 |
| Fun and Games | Bird bean bag toy | 3.49 |
| Furball Inc. | Bird bean bag toy | 3.49 |
| Jouets et ours | Bird bean bag toy | 3.49 |
| Bear Emporium | Rabbit bean bag toy | 3.49 |
| Bears R Us | Rabbit bean bag toy | 3.49 |
| Doll House Inc. | Rabbit bean bag toy | 3.49 |
| Fun and Games | Rabbit bean bag toy | 3.49 |
| Furball Inc. | Rabbit bean bag toy | 3.49 |
| Jouets et ours | Rabbit bean bag toy | 3.49 |
| Bear Emporium | 8 inch teddy bear | 5.99 |
| Bears R Us | 8 inch teddy bear | 5.99 |
| Doll House Inc. | 8 inch teddy bear | 5.99 |
| Fun and Games | 8 inch teddy bear | 5.99 |
| Furball Inc. | 8 inch teddy bear | 5.99 |
| Jouets et ours | 8 inch teddy bear | 5.99 |
| Bear Emporium | 12 inch teddy bear | 8.99 |
| Bears R Us | 12 inch teddy bear | 8.99 |
| Doll House Inc. | 12 inch teddy bear | 8.99 |
| Fun and Games | 12 inch teddy bear | 8.99 |
| Furball Inc. | 12 inch teddy bear | 8.99 |
| Jouets et ours | 12 inch teddy bear | 8.99 |
| Bear Emporium | 18 inch teddy bear | 11.99 |
| Bears R Us | 18 inch teddy bear | 11.99 |
| Doll House Inc. | 18 inch teddy bear | 11.99 |
| Fun and Games | 18 inch teddy bear | 11.99 |
| Furball Inc. | 18 inch teddy bear | 11.99 |
| Jouets et ours | 18 inch teddy bear | 11.99 |
| Bear Emporium | Raggedy Ann | 4.99 |
| Bears R Us | Raggedy Ann | 4.99 |
| Doll House Inc. | Raggedy Ann | 4.99 |
| Fun and Games | Raggedy Ann | 4.99 |
| Furball Inc. | Raggedy Ann | 4.99 |
| Jouets et ours | Raggedy Ann | 4.99 |
| Bear Emporium | King doll | 9.49 |
| Bears R Us | King doll | 9.49 |
| Doll House Inc. | King doll | 9.49 |
| Fun and Games | King doll | 9.49 |
| Furball Inc. | King doll | 9.49 |
| Jouets et ours | King doll | 9.49 |
| Bear Emporium | Queen doll | 9.49 |
| Bears R Us | Queen doll | 9.49 |
| Doll House Inc. | Queen doll | 9.49 |
| Fun and Games | Queen doll | 9.49 |
| Furball Inc. | Queen doll | 9.49 |
| Jouets et ours | Queen doll | 9.49 |
+-----------------+---------------------+------------+
54 rows in set (0.00 sec)
其中,vendors有6行,products有9行。
注意:应该保证所有的联结都有WHERE子句。
12.2.2 内部联结
目前为止所用的联结称为等值联结(equi-join),它基于两个表之间的相等测试。这种联结也称为内部联结。其实,对于这种联结可以使用稍微不同的语法来明确指定联结的类型。
mysql> select vend_name, prod_name, prod_price
    -> from vendors INNER JOIN products
    -> ON vendors.vend_id = products.vend_id;
“正确的”语法——ANSI SQL规范首选INNER JOIN语法。
12.2.3 联结多个表
多做实验——
第13章 创建高级联结
13.1 使用表别名
mysql> select vend_name, prod_name, prod_price
    -> from vendors v, products p
    -> where v.vend_id = p.vend_id;
+-----------------+---------------------+------------+
| vend_name | prod_name | prod_price |
+-----------------+---------------------+------------+
| Bears R Us | 8 inch teddy bear | 5.99 |
| Bears R Us | 12 inch teddy bear | 8.99 |
| Bears R Us | 18 inch teddy bear | 11.99 |
| Doll House Inc. | Fish bean bag toy | 3.49 |
| Doll House Inc. | Bird bean bag toy | 3.49 |
| Doll House Inc. | Rabbit bean bag toy | 3.49 |
| Doll House Inc. | Raggedy Ann | 4.99 |
| Fun and Games | King doll | 9.49 |
| Fun and Games | Queen doll | 9.49 |
+-----------------+---------------------+------------+
9 rows in set (0.00 sec)
注意:Oracle不支持AS关键词。
13.2 使用不同类型的联结
到现在为止,我们使用的只是成为内部联结或等值联结的简单联结。下面来看3中其他联结:自联结、自然联结、外联结。
13.2.1 自联结

13.2.2 自然联结
自然联结:是每个列只返回一次,排除多次出现的列。怎样完成这项工作呢?答案是,系统不完成这项工作,由你自己完成。这一般是对表使用通配符(select *),对所有其他表的列使用明确的子集完成的。
例子略
13.2.3 外部联结
目前为止所用的联结称为等值联结(equi-join),它基于两个表之间的相等测试。这种联结也称为内部联结。
mysql> select vend_name, prod_name, prod_price
    -> from vendors INNER JOIN products
    -> ON vendors.vend_id = products.vend_id;
+-----------------+---------------------+------------+
| vend_name | prod_name | prod_price |
+-----------------+---------------------+------------+
| Bears R Us | 8 inch teddy bear | 5.99 |
| Bears R Us | 12 inch teddy bear | 8.99 |
| Bears R Us | 18 inch teddy bear | 11.99 |
| Doll House Inc. | Fish bean bag toy | 3.49 |
| Doll House Inc. | Bird bean bag toy | 3.49 |
| Doll House Inc. | Rabbit bean bag toy | 3.49 |
| Doll House Inc. | Raggedy Ann | 4.99 |
| Fun and Games | King doll | 9.49 |
| Fun and Games | Queen doll | 9.49 |
+-----------------+---------------------+------------+
9 rows in set (0.03 sec)

与内部联结不同,外部联结包括没有关联的行。下面的例子,LEFT OUTER JOIN选择from子句左边表的所有行。(即,列出所有供货商及其产品,包括没有提供产品的供货商,下面一节——13.3 使用带聚集函数的联结中的例子更直接,更好理解。)
mysql> select vend_name, prod_name, prod_price
    -> from vendors LEFT OUTER JOIN products
    -> ON vendors.vend_id = products.vend_id;
+-----------------+---------------------+------------+
| vend_name | prod_name | prod_price |
+-----------------+---------------------+------------+
| Bear Emporium | NULL | NULL |
| Bears R Us | 8 inch teddy bear | 5.99 |
| Bears R Us | 12 inch teddy bear | 8.99 |
| Bears R Us | 18 inch teddy bear | 11.99 |
| Doll House Inc. | Fish bean bag toy | 3.49 |
| Doll House Inc. | Bird bean bag toy | 3.49 |
| Doll House Inc. | Rabbit bean bag toy | 3.49 |
| Doll House Inc. | Raggedy Ann | 4.99 |
| Fun and Games | King doll | 9.49 |
| Fun and Games | Queen doll | 9.49 |
| Furball Inc. | NULL | NULL |
| Jouets et ours | NULL | NULL |
+-----------------+---------------------+------------+
12 rows in set (0.00 sec)
13.3 使用带聚集函数的联结
对供货商的产品进行计数
mysql> select vend_name, count(prod_name)
    -> from vendors INNER JOIN products
    -> ON vendors.vend_id = products.vend_id
    -> group by vend_name;
+-----------------+------------------+
| vend_name | count(prod_name) |
+-----------------+------------------+
| Bears R Us | 3 |
| Doll House Inc. | 4 |
| Fun and Games | 2 |
+-----------------+------------------+
3 rows in set (0.00 sec)

对供货商的产品进行计数,包括没有提供产品的供货商。
mysql> select vend_name, count(prod_name)
    -> from vendors LEFT OUTER JOIN products
    -> ON vendors.vend_id = products.vend_id
    -> group by vend_name;
+-----------------+------------------+
| vend_name | count(prod_name) |
+-----------------+------------------+
| Bear Emporium | 0 |
| Bears R Us | 3 |
| Doll House Inc. | 4 |
| Fun and Games | 2 |
| Furball Inc. | 0 |
| Jouets et ours | 0 |
+-----------------+------------------+
6 rows in set (0.00 sec)
13.4 使用联结和联结条件
应该提供联结条件,否则会得出笛卡尔积。
第14章 组合查询
14.1 组合查询
有两种情况,需要使用组合查询:
1、在单个查询中从不同的表返回类似的数据结构
2、对单个表执行多个查询,按单个查询返回结果。
14.2 创建组合查询
例子略
14.2.1 使用UNION
例子略
14.2.2 UNION规则
1、UNION语句由两条或两条以上的SELECT语句构成,语句之间工关键字UNION分隔。
2、UNION中的每个查询必须包含相同的列、表达式或聚集函数
14.2.3 包含或取消重复的行
UNION ALL关键字
例子略
14.2.4 对组合查询排序
在组合查询中,ORDER BY子句必须出现在最后一条SELECT语句之后。
例子略
第15章 插入数据
15.1 插入数据
15.1.1 插入完整的行
mysql> INSERT INTO Customers
    ->
    -> VALUES('1000000006',
    ->
    -> 'Toy Land',
    ->
    -> '123 Any Street',
    ->
    -> 'New York',
    ->
    -> 'NY',
    ->
    -> '11111',
    ->
    -> 'USA',
    ->
    -> NULL,
    ->
    -> NULL);
Query OK, 1 row affected (0.06 sec)
上面这种语法虽然简单,但是不安全,应该尽量避免使用。上面SQL语句高度依赖于表中列的定义次序。
更安全的方法如下,在表明后的括号里明确的给出了列明。

mysql> INSERT INTO Customers(cust_id,
    ->
    -> cust_name,
    ->
    -> cust_address,
    ->
    -> cust_city,
    ->
    -> cust_state,
    ->
    -> cust_zip,
    ->
    -> cust_country,
    ->
    -> cust_contact,
    ->
    -> cust_email)
    ->
    -> VALUES('1000000006',
    ->
    -> 'Toy Land',
    ->
    -> '123 Any Street',
    ->
    -> 'New York',
    ->
    -> 'NY',
    ->
    -> '11111',
    ->
    -> 'USA',
    ->
    -> NULL,
    ->
    -> NULL);

15.1.2 插入部分行
列省略:如果表的定语允许,则可在INSERT操作中省略若干列。列省略必须满足以下某个条件:
1、该列定义为允许NULL值。
2、在表定义中给出默认值。
15.1.3 插入检索出的数据
mysql> INSERT INTO Customers(cust_id,
    ->
    -> cust_contact,
    ->
    -> cust_email,
    ->
    -> cust_name,
    ->
    -> cust_address,
    ->
    -> cust_city,
    ->
    -> cust_state,
    ->
    -> cust_zip,
    ->
    -> cust_country)
    ->
    -> SELECT cust_id,
    ->
    -> cust_contact,
    ->
    -> cust_email,
    ->
    -> cust_name,
    ->
    -> cust_address,
    ->
    -> cust_city,
    ->
    -> cust_state,
    ->
    -> cust_zip,
    ->
    -> cust_country
    ->
    -> FROM CustNew;
15.2 从一个表复制到另一个表
mysql> create table custcopy as
    -> select *
    -> from customers;
Query OK, 6 rows affected (0.05 sec)

注意:在试验新SQL语句前,做表的复制是一个很好的习惯。
第16章 更新和删除数据
16.1 更新数据
基本的UPDATE语句由三部分组成:
第2章 要更新的表
第3章 列名和他们的新值
第4章 过滤条件

UPDATE Customers

SET cust_email = 'kim@thetoystore.com'

WHERE cust_id = '1000000005';

注意:不要省略WHERE子句。

要删除某一列的值,可设置它为NULL
UPDATE Customers

SET cust_email = NULL

WHERE cust_id = '1000000005';
16.2 删除数据
DELETE语句有两种使用方法:
1、从表中删除特定的列(使用过滤条件WHERE子句)
2、从表中删除所有行(不使用过滤条件WHERE子句)
mysql> delete from customers
    -> where cust_id = '1000000006';
Query OK, 1 row affected (0.03 sec)

注意:不要省略WHERE子句。

DELETE不需要指定列名或通配符,DELETE删除整行而不是删除指定的列。
为了删除指定的列,请使用UPDATE语句。

如果想从表中删除所有行,不要使用DELETE,请使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快(因为不记录数据的变动)。
16.3 更新和删除的指导原则
下面是许多SQL程序员使用UPDATE和DELETE时所遵循的习惯:
第13章 除非确实打算更新和删除每一行,否则绝对不要使用不带WHERE子句的UPDATE和DELETE语句。
第14章 保证每个表都有主键(详见12章),尽可能像WHERE子句那样使用它(可以指定各主键、多个值或值的范围)。
第15章 在执行带有WHERE子句的UPDATE和DELETE的语句之前,应该先用SELECT进行测试,保证它过滤的是正确的数据。
第16章 使用强制实施应用完整性的数据库(详见12章),这样DBMS将不允许删除具有与其他表相关联的数据的行。
第17章 有的DBMS允许数据库管理员施加约束,以防止不带WHERE子句的UPDATE或DELETE。
第17章 创建和操纵表
17.1 创建表
17.1.1 表创建基础
------------------------
-- Create Products table
------------------------
CREATE TABLE Products
(
  prod_id char(10) NOT NULL ,
  vend_id char(10) NOT NULL ,
  prod_name char(255) NOT NULL ,
  prod_price decimal(8,2) NOT NULL ,
  prod_desc text NULL
);

17.1.2 使用NULL值
关键字:NULL/ NOT NULL
主键和NULL值:主键是一列(或一组列),其值能够唯一标识表中的每一列。所以,只用不允许指定为NULL的列才可用于主键。
注意:NULL与空串('')不同。
17.1.3 制定默认值
关键字:DEFAULT

获得系统日期
MySQL:mysql> select sysdate();
Oracle: SQL> select sysdate from dual;
17.2 更新表结构
以下是使用ALTER TABLE时需要考虑的内容。
第5章 P111暂时略
第6章 。。。
第7章 。。。
可以看出,对已有的表进行更新既复杂又不统一。关于对表的结构能够进行何种更改,请参阅具体的DBMS文档。
mysql> alter table custcopy
    -> add new_id char(100);
Query OK, 6 rows affected (0.13 sec)
Records: 6 Duplicates: 0 Warnings: 0

mysql> alter table custcopy
    -> drop column new_id;
Query OK, 6 rows affected (0.13 sec)
Records: 6 Duplicates: 0 Warnings: 0
复杂的表结构更改一般需要手动删除过程,它涉及以下步骤:
1、复制旧表到一个新表,CREATE TABLE new_table AS SELECT * from old_tables;
2、检验包含所需数据的新表
3、重命名旧表(如果确定,可以删除它)
4、用旧表原来的名字重新命名新表
5、根据需要,重新创建新表的触发器、存储过程、索引和外键。
17.3 删除表
DROP TABLE tablename;
注意:删除表没有确认,也没有撤销。这行这条语句将永久删除该表。
17.4 重命名表名
关键字:RENAME
第18章 使用视图
18.1 视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
理解视图的最好方法是看一个例子。(这是我见过的最好的例子之一——编者注)
mysql> SELECT cust_name, cust_contact
    -> FROM Customers, Orders, OrderItems
    -> WHERE Customers.cust_id = Orders.cust_id
    -> AND OrderItems.order_num = Orders.order_num
    -> AND prod_id = 'RGAN01';
+---------------+--------------------+
| cust_name | cust_contact |
+---------------+--------------------+
| Fun4All | Denise L. Stephens |
| The Toy Store | Kim Howard |
+---------------+--------------------+
2 rows in set (0.06 sec)
该例子从三个表中检索数据,用来检索订购了某类产品的客户。任何需要该数据的人,都需要了解相关表的结构,并且知道如何创建查询和对表进行联结。为了检索其他产品的相同数据,必须修改最后的WHERE子句。
现在,加入可以把整个查询包装成一个名为ProductCustomers的虚拟表,则可以如下轻松的检索出相同的数据:
SELECT cust_name, cust_contact
FROM ProductCustomers
WHERE prod_id = 'RGAN01';
这就是视图的作用。ProductCustomers是一个视图,作为一个视图,它不包含任何数据,它包含的只是一个查询。
18.1.1 为什使用视图
下面是试图的一些常见应用:
1、重用SQL语句。
2、简化复杂的SQL操作。在编写查询后,可以方便的重用它而不必知道它的基本查询细节。
3、使用表的组成部分而不是整个表。
4、保护数据。可以给用户授予特定部分的访问权限,而不是整个表的的访问权限。
5、更改数据格式和表示。试图可返回与底层表不同的格式和表示的数据。

注意:因为试图不包含数据,所以每次使用视图时,都必须处理查询执行时所需的每一个检索。如果你用多个连接和过滤创建了复杂的视图或者嵌套了视图,可能会发现性能下降的很厉害。因此,在使用部署了大量视图的应用前,应该进行测试。
18.1.2 视图的规则和限制
P117,暂时略。
18.2 创建视图
18.2.1 利用视图简化复杂的联结
mysql> CREATE VIEW ProductCustomers AS
    -> SELECT cust_name, cust_contact, prod_id
    -> FROM Customers, Orders, OrderItems
    -> WHERE Customers.cust_id = Orders.cust_id
    -> AND OrderItems.order_num = Orders.order_num;
Query OK, 0 rows affected (0.00 sec)
18.2.2 用视图重新格式化检索出的数据

18.2.3 用视图过滤不想要的数据
过滤没有电子邮件地址的客户
mysql> CREATE VIEW CustomerEMailList AS
    -> SELECT cust_id, cust_name, cust_email
    -> FROM Customers
    -> WHERE cust_email IS NOT NULL;
Query OK, 0 rows affected (0.08 sec)
18.2.4 使用视图与计算字段
mysql> CREATE VIEW OrderItemsExpanded AS
    -> SELECT order_num,
    -> prod_id,
    -> quantity,
    -> item_price,
    -> quantity*item_price expanded_price
    -> FROM OrderItems;
Query OK, 0 rows affected (0.03 sec)
18.3 小结
视图是虚拟的表,他不包含的不是数据,而是根据需要检索数据的查询。
试图提供了一种封装SELECT语句的层次,可用来简化数据处理、重新格式化基础数据或保护基础数据。
第19章 使用存储过程

附录: Oracle 和 mysql 的一些简单SQL操作命令对比
  
        Oracle mysql
对比版本 Personal Oracle7 Release 7.3.4.0.0 mysql 3.23.58-nt
默认安装目录 C:ORAWIN95 F:MySQL
各种实用程序所在目录 C:ORAWIN95BIN F:MySQLBIN
控制台工具 SVRMGR.EXE SVRMGR23.EXE mysqladmin.exe
数据库启动程序 0start73.exe screen mysqld-shareware.exe
关闭数据库命令 ostop73.exe mysqladmin.exe -u root shutdown
客户程序 SQL*Plus mysql
启动命令 c:orawin95binsqlplus.exe F:MySQLbinmysql.exe
带用户启动方式 (直接连库方式) c:orawin95binsqlplus.exe system/manager@TNS F:MySQLbinmysql.exe test F:MySQLbinmysql.exe -u root test
安装后系统默认用户(库) sys system scott mysql test
显示所有用户(库) SQL >select * from all_users; F:MySQLbin>mysqlshow F:MySQLbin>mysqlshow --status mysql> show databases;
退出命令 SQL> exit SQL> quit mysql> exit mysql> quit
改变连接用户(库) SQL> conn 用户名/密码@主机字符串 mysql> use 库名
查询当前所有的表 SQL> select * from tab; SQL> select * from cat; mysql> show tables; F:MySQLbin>mysqlshow 库名
显示当前连接用户(库) SQL> show user mysql> connect
查看帮助 SQL> ? mysql> help
显示表结构 SQL> desc 表名 SQL> describe 表名 mysql> desc 表名; mysql> describe 表名; mysql> show columns from 表名; F:MySQLbin>mysqlshow 库名 表名
拼接字段 ||或者+ CONCAT( ) 函数
日期函数 SQL> select sysdate from dual; mysql> select sysdate( );
mysql> select now( );
mysql> select curdate( );
mysql> select current_date;
mysql> select curtime( );
mysql> select current_time;
日期格式化 SQL> select to_char(sysdate,'yyyy-mm-dd') from dual;
 SQL> select to_char(sysdate,'hh24-mi-ss') from dual; mysql> select date_format(now(),'%Y-%m-%d');
 mysql> select time_format(now(),'%H-%i-%S');
日期函数 (增加一个月) SQL> select to_char(add_months(to_date('20000101','yyyymmdd'),1),'yyyy-mm-dd') from dual; 结果:2000-02-01 SQL> select to_char(add_months(to_date('20000101','yyyymmdd'),5),'yyyy-mm-dd') from dual; 结果:2000-06-01 mysql> select date_add('2000-01-01',interval 1 month); 结果:2000-02-01 mysql> select date_add('2000-01-01',interval 5 month); 结果:2000-06-01
别名 SQL> select 1 a from dual; mysql> select 1 a;
mysql> select 1 as a;
字符串截取函数 SQL> select substr('abcdefg',1,5) from dual; SQL> select substrb('abcdefg',1,5) from dual; 结果:abcde mysql> select substring('abcdefg',2,3); 结果:bcd mysql> select mid('abcdefg',2,3); 结果:bcd mysql> select substring('abcdefg',2); 结果:bcdefg mysql> select substring('abcdefg' from 2); 结果:bcdefg 另有SUBSTRING_INDEX(str,delim,count)函数 返回从字符串str的第count个出现的分隔符delim之后的子串。 如果count是正数,返回最后的分隔符到左边(从左边数) 的所有字符。 如果count是负数,返回最后的分隔符到右边的所有字符(从右边数)。
执行外部脚本命令 SQL >@a.sql 1:mysql> source a.sql 2:F:MySQLbin>mysql 3:F:MySQLbin>mysql 库名
导入、导出工具 exp.exe exp73.exe imp.exe imp73.exe mysqldump.exe mysqlimport.exe
改表名 SQL> rename a to b; mysql> alter table a rename b;
执行命令 ;<回车> / r run ;<回车> go ego
distinct用法 SQL> select distinct 列1 from 表1; SQL> select distinct 列1,列2 from 表1; mysql> select distinct 列1 from 表1; mysql> select distinct 列1,列2 from 表1;
注释 -- /*与*/ # -- /*与*/
当作计算器 SQL> select 1+1 from dual; mysql> select 1+1;
限制返回记录条数 SQL> select * from 表名 where rownum<5; mysql> select * from 表名 limit 5;
新建用户(库) SQL> create user 用户名 identified by 密码; mysql> create database 库名;
删用户(库) SQL> drop user 用户名; mysql> drop database 库名;
外连接 使用(+) 使用left join
查询索引 SQL> select index_name,table_name from user_indexes; mysql> show index from 表名 [FROM 库名];
通配符 “%” “%”和“_”
SQL语法 SELECT selection_list 选择哪些列 FROM table_list 从何处选择行 WHERE primary_constraint 行必须满足什么条件 GROUP BY grouping_columns 怎样对结果分组 HAVING secondary_constraint 行必须满足的第二条件 ORDER BY sorting_columns 怎样对结果排序 SELECT selection_list 选择哪些列 FROM table_list 从何处选择行 WHERE primary_constraint 行必须满足什么条件 GROUP BY grouping_columns 怎样对结果分组 HAVING secondary_constraint 行必须满足的第二条件 ORDER BY sorting_columns 怎样对结果排序 LIMIT count 结果限定

展开全文


推荐文章

猜你喜欢

附近的人在看

推荐阅读

拓展阅读