MYSQL-多表查询
1.多表关系
项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:
- 一对多(多对一) - 案例:部门与员工的关系 - 关系:一个部门对应多个员工,一个员工对应一个部门 - 实现:在多的一方建立外键,指向一的一方的主键 
- 多对多 - 案例:学生和课程的关系 - 关系:一个学生可以选修多门课程,一门课程也可以供多个学生选择 - 实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键  
- 一对一 - 案例:用户与用户详情的关系 - 关系:一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率 - 实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)   
2.多表查询概述
概述:指从多张表中查询数据
多表查询分类:
- 连接查询 - 内连接:相当于查询A、B交集部分数据(两表之间的交集数据) - 外连接:左外连接:查询左表所有数据,以及两张表交集部分数据 右外连接:查询右表所有数据,以及两张表交集部分数据 - 自连接:当前表与自身的连接查询,自连接必须使用表别名 
- 子查询 
内连接
| 1 | # 隐式内连接 | 

外连接
| 1 | # 左外连接 | 


自连接
自链接查询可以是内连接查询也可以是外连接查询
| 1 | select 字段列表 from 表a 别名a join 表a 别名b on 条件; | 

子查询:
概念:SQL语句中嵌套select语句为嵌套查询,又称子查询
| 1 | select * from 表1 where 字段=(select 字段 from 表2); | 
子查询外的语句可以是insert、update、delete、select中的一个
根据子查询的结构不同,分为:
- 标量子查询:子查询结果为一个单个值 - 常用符号:=、<>、>、>=、<、<= - 1 
 2
 3
 4
 5
 6
 7
 8- # 根据销售部门的id查询员工信息 
 # 先分开查询
 # 查询销售部门的id
 select id from dept where name='销售部'; #id为4
 # 查询销售部门中员工的信息
 select * from emp where dept_id=4;
 # 合并为一个查询
 select * from emp where dept_id=(select dept.id from dept where dept.name='销售部' );
- 列子查询:子查询的结果为一列 - 常用操作符:  - 1 
 2
 3
 4
 5
 6
 7
 8- # 列子查询 
 # 查询销售部和市场部的所有员工信息
 # 查询销售部和市场部的id
 select id from dept where name='销售部' or name='市场部'; #id为2 4
 # 查询两个部门的所有员工
 select * from emp where dept_id in (2,4);
 # 合并
 select * from emp where dept_id in (select id from dept where name='销售部' or name='市场部');
- 行子查询:子查询的结果为一行 - 常用操作符:=、<>、in、not in - 1 
 2
 3
 4
 5
 6- # 查询与张无忌的薪资及直属领导相同的员工信息 
 # 查询张无忌的薪资和直属领导
 select salary, managerid from emp where name='张无忌';
 # 查询与张无忌的薪资及直属领导相同的员工信息
 select * from emp where (salary,managerid)=(select salary, managerid from emp where name='张无忌');
- 表子查询:查询结果为多行多列5 - 多表查询案例 - 常用操作符:in - 1 - #询与鹿杖客和宋远桥的职位和薪资相同的员工信息select * from emp where (job, salary) in ( select job, salary from emp where name in ('鹿杖客', '宋远桥')); - 表子查询的子表作为临时表 - 1 
 2
 3
 4- # 查询入职日期是’2006-01-01‘之后的员工信息和部门信息 
 # 先查询出入职在’2006-01-01‘之后员工的所有信息
 # 与部门表左连接
 select e.*, dept.* from (select * from emp where entrydate>'2006-01-01') e left outer join dept on e.dept_id=dept.id;
多表查询操作:


1.查询员工的姓名,年龄,职位,部门信息(隐式内连接)
| 1 | select e.name,e.age,e.job,d.* from emp e,dept d where e.dept_id=d.id; | 

2.查询年龄小于30的员工的姓名,年龄,职位,部门信息(显式内连接)
| 1 | select emp.name,emp.age,emp.job,dept.* from emp inner join dept on emp.dept_id = dept.id where emp.age<30; | 

3.查询拥有员工的部门id,部门名称
| 1 | select distinct d.id,d.name | 
4.查询所有年龄大于40的员工,及其归属部门名称,如果员工没有分配部门也要显示
| 1 | select e.*,d.name | 
5.查询所有员工的工资等级
| 1 | select e.*,s.grade | 
6.查询研发部所有员工的信息即工资等级
| 1 | select e.*,s.grade | 
7.查询研发部员工的平均工资
| 1 | select avg(e.salary) | 
8.查询工资比灭绝高的员工信息
| 1 | select * | 
9.查询比平均薪资高的员工信息
| 1 | select * | 
10.查询低于本部门平均工资的员工信息
| 1 | select * | 
11.查询所有部门信息,并统计部门的员工人数
| 1 | select d.*, ( |