关联查询
1、概念:
当在查询时,我们所需要的数据不在一张表中,可能在
两张表或多张表中。此时我们需要同时操作这些表。即
关联查询。
2、等值连接:
在做多张表查询时,这些表中应该存在着有关联的两个字段。
我们使用某一张表中的一条记录与另外一张表通过相关联
的两个字段进行匹配,组合成一条记录。
--查询部门表的名称及其每个部门的员工的员工编号和姓名及其职位,部门号。按照部门号降序排序。
select dept.deptno, dname, empno,ename,job
from emp,dept
where emp.deptno=dept.deptno
order by emp.deptno desc;
3、笛卡尔积:
在做多张表查询时,我们使用某一张表中的每一条记录都与
另外一张表的所有记录进行组合。比如表A有x条,表B
有y条件,最终组合数为x*y,这个值就是笛卡尔积,通常
没有意义。
4、内连接
只要使用了join on。就是内连接。查询效果与等值连接一样。
用法:
表A [inner] join 表B on 关联条件
--查询部门表的名称及其每个部门的员工的员工编号和姓名及其职位,部门号。按照部门号降序排序。
select dept.deptno, dname, empno,ename,job
from emp join dept
on emp.deptno=dept.deptno
order by emp.deptno desc;
5、外连接:
在做多张表查询时,我们所需要的数据,除了满足关联条件
的数据外,还有不满足关联条件的数据。此时需要使
用外连接。会涉及到两个概念:
驱动表(主表):除了显示满足条件的数据,还需要显示不满足条件的数据的表
从表(副表):只显示满足关联条件的数据的表
- 外连接分为三种:
-
左外连接:
表A left [outer] join 表B on 关联条件。
表A是驱动表,表B是从表 -
右外连接
表A right [outer] join 表B on 关联条件
表B是驱动表,表A是从表 -
全外连接:
两张表的数据不管满不满足条件,都做显示。
表A full [outer] join 表B on 关联条件
PS:mysql 不支持全外连接
6、自连接:
在多张表进行关联查询时,这些表的表名是同一个。
即自连接。
--查询领导的姓名及其下属的姓名。
select m.ename "领导姓名",e.ename "员工姓名"
from emp e join emp m
on e.mgr = m.empno;
高级关联查询:
有的时候,我们要查询的数据, 一个简单的查询语句
满足不了,并且我们使用的数据,表中不能直观体现出来。
而是预先经过一次查询才会有所体现。那么先执行的
查询,我们称之子查询。被子查询嵌入的查询语句称之
为父查询。
- 子查询返回的数据特点:
-
(1) 可能是单行单列的数据。可以直接使用条件运算符(=,<,>,<=,>=,!=,<>)连接
-
(2) 可能是多行单列的数据。可以使用()将涉及的字段名全部绑定在一起,再使用条件运算符连接
-
(3) 可能是单行多列的数据。和(1)大致相同,只是不使用条件运算符,而是使用in ,all,any等
-
(4) 可能是多行多列的数据。和(2)大致相同,也使用in,all,any等关键词连接
1)子查询可以在where子句中
--查询工资大于员工JONES工资的员工的信息
select *
from emp
where sal>(select sal
from emp
where ename='jones');
2)子查询可以在from子句中
--查询每个员工的工资,姓名和其部门的平均工资。
select sal,ename,avg_sal
from emp join (
select deptno,avg(ifnull(sal,0)) 'avg_sal'
from emp
group by deptno) t
on emp.deptno = t.deptno
order by t.deptno;
3)子查询可以在having子句中
--查询部门平均工资大于30部门平均工资的部门平均工资,工资之和,
--最大工资,最小工资,总人数。
select deptno,avg(ifnull(sal,0)),sum(sal),max(sal),min(sal),count(*)
from emp
group by deptno
having avg(ifnull(sal,0))>(
select avg(ifnull(sal,0))
from emp
where deptno=30);
4)子查询可以在select字句中,相当于外连接的另外一种写法。
--查询每个员工的姓名,工资,及其部门的平均工资,工资之和。
select ename,sal,(
select avg(ifnull(sal,0))
from emp a
where a.deptno=b.deptno) avg_sal ,(
select sum(sal)
from emp c
where c.deptno=b.deptno ) sum_sal
from emp b order by b.deptno;