多表查询基本就是对笛卡尔积做筛选
类型:
等值连接(easy)
不等值连接(easy)
外连接
自连接
1、等值连接
select e.empno,e.ename,e.sal,d.dname
from emp e, dept d
where e.deptno = d.deptno
2、不等值连接
select e.empno,e.ename,e.sal,s.grade
from emp e,salgrade s
where e.sal between s.losal and s.hisal;
3、外连接
例子:按部门统计员工信息:部门号 部门名称 人数
错误,没有所有部门(没有人的部门没有显示):
select d.deptno 部门号,d.dname 部门名称,count(e.ename) 人数
from emp e,dept d
where e.deptno=d.deptno
group by d.deptno,d.dname;
正确:
select d.deptno 部门号,d.dname 部门名称,count(e.ename) 人数
from emp e,dept d
where e.deptno(+)=d.deptno
group by d.deptno,d.dname;
左外连接:where e.deptno=d.deptno不成立的时候,等候左边的表仍然包含在最后的结果中
写法:where e.deptno=d.deptno(+)
右外连接:where e.deptno=d.deptno不成立的时候,等候右边的表仍然包含在最后的结果中
写法:where e.deptno(+)=d.deptno
总结:要全部显示的表不写加号
4、自连接
通过表的别名,讲同一张表视为多张表
例子:查询员工名字 老板名字
select e.ename 员工姓名,b.ename 老板姓名
from emp e,emp b
where e.mgr=b.empno;
问题:这也是相当于在笛卡尔积上做筛选,验证:
select count(*)
from emp e,emp b;
结果时表记录数的平方
如果表记录有个一亿条,那么一亿的平方。。。。
所以,自连接不适合操作大表
接下来,引入层次查询
5、层次查询(单表查询)
相当于树,如下图:
select level,empno,ename,mgr
from emp
connect by prior empno=mgr
start with mgr is null(start with empno=7839)
order by 1;
level:伪列
prior:上一层,这里表示上一层的员工列等于这一层的老板列
运行结果如下: