SQL——多表连接查询
若一个查询同时涉及两个或两个以上的表, 则称之为连接查询(在FROM子句中体现)。 参与连接的表可有多个,但连接操作在两个表之间进行,即两两连接。
连接查询包括:
- 内连接
- 等值连接:用“=”比较被连接列的列值
- 非等值连接:用“>、>=、<、<=、<>”号进行比较运算
- 自连接:特殊的内连接,一张表看成两张表,自己连接自己,必须给表取别名
- 外连接
- 左外
- 右外
- 前外
- 交叉连接
1 内连接
执行连接操作的过程:
先取表1中的第1个元组,然后从头开始扫描表2,逐一查找满足连接条件的元组;
找到后就将表1中的第1个元组与该元组拼接起来,形成结果表中的一个元组。
表2全部查找完毕后,再取表1中的第2个元组,然后再从头开始扫描表2, …
重复这个过程,直到表1中的全部元组都处理完毕为止。
select ...
from tablename [inner] join 被连接表
on 连接条件
......
——举例(引用已有数据库:bjpowernode.sql)
dept:部门表 | emp:员工表 | salgrade :工资等级表 |
deptno:部门编号 | empno:员工编号 | grade:等级 |
dname:部门名称 | ename:员工名字 | losal:最低薪资 |
loc:部门位置 | job:工作岗位 | hisal:最高薪资 |
mgr:上级领导编号 | ||
hiredate:入职时间 | ||
sal:月薪 | ||
comm:补助/津贴 | ||
deptno:部门编号 |
1.1 等值连接
查询每个员工的部门名称,显示员工名和部门名。
select ename,dname
from emp e join dept d
on e.deptno=d.deptno;
1.2 非等值连接
查询每个员工的工资等级,显示员工名、工资、工资等级。
select ename,sal,grade
from emp e join salgrade s
on e.sal between s.losal and s.hisal;
1.3 自连接
特殊的内连接——相互连接的表物理上为同一张表。
必须为两个表取别名,使之在逻辑上成两个表(一个是查询结果表,一个查询条件表)。 注:为表指定别名时,在查询语句中其它地方, 所有用到表名处均要用别名,不能再用原表名。
<表名> [AS] <表别名> (注意与列别名的区别,group by 后不能用列别名)
查询某个员工的上级领导,显示员工名和对应的领导名。
注:员工的领导编号=领导的员工编号
select a.ename as '员工名',b.ename as '领导名'
from emp a inner join emp b
on a.mgr=b.empno;
2 外连接
只限制一张表中数据必须满足连接条件, 而另一张表中数据可不满足连接条件。
外连接与普通连接的区别: 普通连接操作只输出满足连接条件的元组
外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出
左外连接:列出左边关系中所有的元组
右外连接:列出右边关系中所有的元组
# 1.ANSI方式的外连接的语法格式为:
FROM 表1 LEFT | RIGHT |FULL [OUTER]
JOIN 表2 ON <连接条件>
# 2.theta方式的外连接的语法格式为:
# 左外连接(输出表1中所有内容):
FROM 表1, 表2 WHERE [表1.]列名(+) = [表2.]列名
# 右外连接(输出表2中所有内容):
FROM 表1, 表2 WHERE [表1.]列名= [表2.]列名(+)
2.1 左外连接
查询每个员工的上级领导。
注:主要查询左边的员工表
select a.ename as '员工', b.ename '领导'
from emp a left join emp b
on a.mgr=b.empno;
2.1 右外连接
查询每个员工的上级领导。
注:主要查询右边的领导表
select a.ename as '员工', b.ename '领导'
from emp a right join emp b
on a.mgr=b.empno;
查询哪个部门没有员工。
注:主要的表是部门表,用right 使用where e.empno is null
select d.*
from emp e right join dept d
on e.deptno=d.deptno
where e.empno is null;
3 三张表连接
查询每个员工的部门名称和工资等级。
注:使用emp表dept表先进行连接,再将emp表和salgrade表连接
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;
查询每个员工的部门名称、工资等级和上级领导。
注:不能在第一个join进行左外连接
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;