在实际的查询中,大部分的查询都不是从单表去查询数据,一般都是多张表联合查询取出最终的结果;一般一个业务对应多张表,比如:员工和部门,起码两张表
为什么一个业务要对应多张表呢?对应一张表不行吗?
试想一下,如果员工和部门信息存储到一张表中,那么每个员工的后面都会对应一个部门信息,数据会出现大量的重复,导致数据的冗余,从而占用更多的底层空间
EMP(员工表)
EMPNO|ENAME |JOB |MGR |HIREDATE |SAL |COMM|DEPTNO|
-----|------|---------|----|----------|----|----|------|
7369|smith |clerk |7902|1980-12-17| 800| | 20|
7499|allen |salesman |7698|1981-02-20|1600| 300| 30|
7521|ward |salesman |7698|1981-02-22|1250| 500| 30|
7566|jones |manager |7839|1981-04-02|2975| | 20|
7654|martin|salesman |7698|1981-09-28|1250|1400| 30|
7698|blake |manager |7839|1981-05-01|2850| | 30|
7782|clark |manager |7839|1981-06-09|2450| | 10|
7788|scott |analyst |7566|1987-04-19|3000| | 20|
7839|king |president| |1981-11-17|5000| | 10|
7844|turner|salesman |7698|1981-09-08|1500| 0| 30|
7876|adams |clerk |7788|1987-05-23|1100| | 20|
7900|james |clerk |7698|1981-12-03| 950| | 30|
7902|ford |analyst |7566|1981-12-03|3000| | 20|
7934|miller|clerk |7782|1982-01-23|1300| | 10|
DEPT(部门表)
DEPTNO|DNAME |LOC |
------|----------|--------|
10|accounting|new york|
20|research |dallas |
30|sales |chicago |
40|operations|boston |
SALGRADE(薪资等级表)
GRADE|LOSAL|HISAL|
-----|-----|-----|
1| 700| 1200|
2| 1201| 1400|
3| 1401| 2000|
4| 2001| 3000|
5| 3001| 9999|
假设A和B表进行连接,凡是A表和B表能够匹配上的记录查询出来,这就是内连接
AB两张表没有主副之分,两张表是平等的
条件是等量关系
案例:查询每个员工的部门名称,要求显示员工名和部门名
select
e.ename as 员工,d.dname as 部门
from
emp e
join
dept d
on e.deptno = d.deptno
员工 | 部门 |
------|----------|
clark |accounting|
king |accounting|
miller|accounting|
smith |research |
jones |research |
scott |research |
adams |research |
ford |research |
allen |sales |
ward |sales |
martin|sales |
blake |sales |
turner|sales |
james |sales |
条件是非等量关系
案例:查找出每个员工的工资等级,要求显示员工名,工资,工资等级
select
e.ename as 员工,e.sal as 工资,s.grade as 工资等级
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal
员工 |工资 |工资等级|
------|----|----|
smith | 800| 1|
allen |1600| 3|
ward |1250| 2|
jones |2975| 4|
martin|1250| 2|
blake |2850| 4|
clark |2450| 4|
scott |3000| 4|
king |5000| 5|
turner|1500| 3|
adams |1100| 1|
james | 950| 1|
ford |3000| 4|
miller|1300| 2|
自己连自己,把一张表看成两个表
案例:找出员工的上级领导,要求显示员工和上级领导
select
a.ename as 员工,b.ename as 上级领导
from
emp a
join
emp b
on
a.mgr = b.empno
员工 |上级领导 |
------|-----|
smith |ford |
allen |blake|
ward |blake|
jones |king |
martin|blake|
blake |king |
clark |king |
scott |jones|
turner|blake|
adams |scott|
james |blake|
ford |jones|
miller|clark|
假设A和B表进行连接,AB两张表有一张是主表,有一张是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配
注意:每一个左连接都有一个右连接的写法,每一个右连接也有一个左连接的写法
表示左边的表是主表
案例:找出每个员工的上级领导,所有员工必须查询出来
select
a.ename as 员工,b.ename as 上级领导
from
emp a
left join
emp b
on
a.mgr = b.empno
表示右边的表是主表
案例:找出哪个部门没有员工
select
d.*
from
emp e
right join
dept d
on
e.deptno = d.deptno
where
e.empno is null
DEPTNO|DNAME |LOC |
------|----------|------|
40|operations|boston|
找出每个员工的部门名称,工资等级
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on e.sal between s.losal and s.hisal
ename |dname |grade|
------|----------|-----|
smith |research | 1|
allen |sales | 3|
ward |sales | 2|
jones |research | 4|
martin|sales | 2|
blake |sales | 4|
clark |accounting| 4|
scott |research | 4|
king |accounting| 5|
turner|sales | 3|
adams |research | 1|
james |sales | 1|
ford |research | 4|
miller|accounting| 2|
找出每个员工的部门名称,工资等级,以及领导
select
e.ename,d.dname,s.grade,e1.ename
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp e1
on
e.mgr = e1.empno
ename |dname |grade|ename|
------|----------|-----|-----|
smith |research | 1|ford |
allen |sales | 3|blake|
ward |sales | 2|blake|
jones |research | 4|king |
martin|sales | 2|blake|
blake |sales | 4|king |
clark |accounting| 4|king |
scott |research | 4|jones|
king |accounting| 5| |
turner|sales | 3|blake|
adams |research | 1|scott|
james |sales | 1|blake|
ford |research | 4|jones|
miller|accounting| 2|clark|