第11章 多表查询(重点,难点)
11.1 基本介绍
多表查询是指基于两个和两个以上的表或是视图的查询.在实际应用中,查询单个表可能不能满足你的需求,(如显示sales部门位置和其员工的姓名),这种情况下需要使用到(dept表和emp表)
11.2 看一个实际的需求
- 显示雇员名(ename),雇员工资(sal)及所在部门的名字(dname)?
- 分析
(1) 因为字段的信息来自于两个表 emp, dept 表,因此对其联合查询
(2) 如果直接对两个联查,将会得到这样的结果=>笛卡尔集
- 笛卡尔集
当我们对多表进行联查时,我们就会得到的 表1记录数 * 表2的记录数,如图:
- 对这个需求的完成和分析
- 关于笛卡尔集的说明
规定:多表查询的条件是 至少不能少于 表的个数-1
- 多表查询的练习
11.3 自连接
- 基本介绍: 自连接是指在同一张表的连接查询
- 案例:
?显示某个员工的上级领导的姓名,比如显示’FORD’的上级.
- 案例:
- 分析:
11.4 子查询
- 基本的介绍
子查询是指嵌入在其它sql查询语句中的select语句,也叫嵌套查询
- 单行子查询
单行子查询是指只返回一行数据的子查询语句
请思考:如何显示与SMITH同一部门的所有员工?
- 多行子查询
多行子查询指返回多行数据的子查询 使用关键字 in
案例:
分析
(1) 应该查询到10号部门有哪些工作
select distinct job from emp where deptno =10;
(2) 有哪些雇员是这样的工作
select * from emp where job in (select distinct job from emp where deptno =10) and deptno <> 10;
11.5 作业练习-查询ecshop表的ecs_goods表的各个类别的价格最高商品信息
11.6 多列子查询
- 基本介绍
如果我们的一个子查询,返回的结果是多列的,我们就把这个子查询叫做多列子查询.
select math, english, chinese from student where name = '宋江';
select * from student where (math, english, chinese) = (select math, english, chinese from student where name = '宋江');
11.7 在from子句中使用子查询
如果我们的子查询他是在,from子句中出现的,则我们就叫from子句的子查询.
l 案例:
请思考:如何显示高于自己部门平均工资的员工的信息(名字,薪水,和该部门的平均薪水)
(1) 查出各个部门的平均工资
select avg(sal) as myavg , deptno from emp group by deptno;
(2) 就把上面的查询当做一个临时表来使用
select ename, sal, temp. myavg,emp.deptno from
emp, (select avg(sal) as myavg , deptno from emp group by deptno) as temp
where
emp.deptno = temp.deptno
AND
emp.sal > temp. myavg;
案例
查找每个部门工资最高的人的详细资料(雇员们,薪水,部门编号,最高工资
(1) 查询出各个部门的最高工资
select max(sal) as mymax, deptno from emp group by deptno;
(2) 把上面的查询当做一个临时表
select ename, sal, emp.deptno, temp.mymax from
emp , (select max(sal) as mymax, deptno from emp group by deptno) AS temp
where emp.deptno = temp.deptno and sal = temp.mymax;
11.8 课后练习
11.9 自我复制数据
有时,为了对某个sql语句进行效率测试,我们需要海量数据时,可以使用此法为表创建海量数据. 如快速的创建一张海量表.1000w [实践...工科]
(1) 创建一张结构相同的表
create table temp_emp like emp;
(2) 将emp的数据导入的temp_emp
(3) 自我复制
11.10 如何对一张表去复制
- 对student表的数据去重.
(1) 创建一张结构相同的表
(2) 将过滤distinct 数据导入的 temp_stu中.
(3) 删除stu表->将temp_stu改名student
11.11 合并查询
- 基本介绍: 合并查询有两种,union / union all 。
- union 合并查询
基本语法:
select 语句1 union select语句2 ....;
将第一个sql语句的结果和第二个sql语句结果合并返回,而且会去掉重复的记录.
- 举例说明
- union all
union all 和 union 的用法一样,但是union all 不会去掉重复记录.
第12章 多mysql表的内连接和外连接
12.1 mysql表的内连接
- 基本介绍:内连接实际上就是利用 where 子句对两张(多表)表形成的笛卡尔积进行筛选,我们前面学习的查询都是内连接,也是在开发过程中用的最多的连接查询。
- 基本语法
(1) 前面我们使用的那种语法.
(2) 还有一种写法
select 列名 from 表1 inner join 表2 inner join 表3 ON 条件 ....
<=等价==>
select 列名 from 表1 , 表2 , 表3 WHERE 条件 ....
l 举例说明
雇员的名字,薪水,部门的名称.
12.2 基本介绍mysql的外连接
mysql的外连接有两种,左外连接,右外连接。【完全外连接[mysql中支持语法,但是没有实际用处]】
- 左外连接
基本介绍: 如果左侧的表完全显示我们就说是左外连接
基本语法:
select 列名 from 表1 left join 表2 ON 条件 .....
案例说明:
(1) 创建两张表,并添加了数据
(2)显示所有人的成绩,如果没有成绩,也要显示该人的姓名和id号,成绩显示为空
- 右外连接
基本介绍: 如果右侧的表完全显示我们就说是右外连接
基本语法:
select 列名 from 表1 right join 表2 ON 条件 .....
案例说明:
查询结果要求:如果一个成绩,没有对应的人,则显示 '无名' , '未知id'
- 练习题
(1) 先将学生的信息全部显示
select stu.id,name,grade from stu left join exam on stu.id = exam.id;
(2) 将考试成绩都显示出来
select stu.id,name,grade from stu right join exam on stu.id = exam.id;
(3) union
select stu.id,name,grade from stu left join exam on stu.id = exam.id union
select stu.id,name,grade from stu right join exam on stu.id = exam.id;
练习2
(1) 使用左外连接
(2) 使用右外连接
第13章 mysql的结束
13.1 基本的介绍
约束是用于维护数据的完整性, 所谓数据的完整性指的是,就是根据业务逻辑的需要,我们将表的某些字段设置成一种约束,从而保证数据的合理性和完整性,比如身份证编号就是唯一,我们就可以使用unique 这个约束.
13.2 mysql的约束分类
主要有五种 :
(1) 主键约束: primary key
(2) 唯一约束: unique
(3) not null
(4) check :检查约束,很多数据库都有,但是mysql支持语法,并没有实际作用
(5) 外键约束: foreign key
13.3 主键约束
- 基本语法
说明
(1) 主键约束一般在int , 字符型设置
(2) 一旦一个字段被设置成主键约束,则该字段不能重复,也不能为null
l 案例
13.4 基主键的使用细节说明(使用陷进)
(1) primary key不但不能重复而且不能为null
(2) 一张表最多只能有一个主键, 但可以是复合主键
举例:
举例2:
(3) 一般来说一张表总有primary key ,而且是整数类型的, 以后同学们这样使用 即可.
看一个:ecs_goods 和 ecs_vote;
(4) 主键的指定方式 有两种
在字段后面直接定义
在字段定义完毕后,在后面写.
(5) 如果有一个主键后,还希望其它字段达到not null 并且 unique 的效果,则可以如下定义表
13.5 not null约束
not null 前面已经使用很多次,这里我们就不讲了.
13.6 unique约束(唯一约束)
当我们希望某个字段的值不能出现重复值时,我们就可以将该字段设置成unique.
- 基本语法
字段名 字段类型 unique,
- 举例说明
13.7 unique细节
(1) 如果我们将某个字段设置为 unique ,但是没有设置 not null, 那么该字段可以为null,并且可以有多个null
(2) 如果你要某个字段不能重复,而且不能为 null, 我们可以这样定义字段
字段名 字段类型 not null unique
(3) 一个表中,可以有多个unique约束.
13.8 外键约束
- 基本的介绍
用于定义主表和从表之间的关系: 外键约束要定义在从表上,主表则必须具有主键约束或是unique约束.,当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为null。
- 外键的基本语法
foreign key (外键字段) references 主表(字段);
说明:
(1) 红字是关键字,规定好.
(2) 外键字段 在本表定义的。
(3) 外键字段是指向另外一张表的某个字段.
看一个实际的需求
- 基本案例说明
(1) 先创建主表/从表
(2) 当有外键有,在使用的时候有如下注意事项
ü 当给从表添加记录时,要外键的值已经在主表中存在,否则不能添加成功
ü 如果我们的外键没有设置 not null, 那么外键的值可以是 null, 而且可以有多个.
(3)使用一把
(4) 外键的使用细节
ü 外键指向的表的字段,要求是primary key 或者是 unique
ü 表的类型是innodb, 这样的表才支持外键
ü 外键字段的类型要和主键/unqiue字段的类型一致(长度可以不同)
ü 外键字段的值,必须在主键字段中出现过,或者为null [前提是外键可以为null]
ü 一旦建立主外键的关系,数据不能随意删除和修改了[参照完整性]
不指定外键,同样可以有不同表的字段相关联的关系,只是这种关系的维护,要由程序员自己维护(php),mysql数据库不会去检查了
13.9 check约束(了解)
说明:
check约束在mysql中,支持语法,但是没有作用!
13.10 约束的综合练习题-练习约束
13.11 练习题
晚上把下面这个综合案例完成
13.12 如何对约束进行管理(增、删、改、查)
在实际开发中,对表的约束的管理是重要的,因此要求大家必须掌握.
create table customer2 (
customer_id char(8) not null default '',
name varchar(20),
address varchar(30) not null default '',
email varchar(30) ,
sex enum('男','女') not null);
上面这个表有问题 ,看看需求
(1) 客户号设为的主键;
alter table customer2 add primary key (customer_id);
(2) 客户的姓名不能为空值;
alter table customer2 modify name varchar(20) not null default '';
(3) 电邮不能够重复;--增加身份证也不重复
alter table customer2 add unique(email);
(4) 客户的住址默认是'泰牛学生宿舍'
alter table customer2 modify address varchar(30) not null default '泰牛学生宿舍';
13.13 晚上练习
13.14 删除约束的讲解
当不再需要某个约束时,可以删除
(1) 删除主键约束
因为一个表只有一个主键,所以主键的删除非常的简单.
alter table customer2 drop primary key;
(2) 删除not null, unique , 修改字段
(3) 删除外键约束
第一步先查询外键的名称
删除:
alter table stu drop foreign key stu_ibfk_1;