什么是笛卡尔积?
Oracle的连接条件的类型
- 等值连接
- 不等值连接
- 外连接
- 自连接
Oracle多表连接示例
1.多表连接基本查询
使用一张以上的表做查询就是多表查询
语法:
SELECT {DISTINCT} *|列名... FROM 表明 别名, 表名1 别名
{WHERE 限制条件 ORDER BY 排序字段 ASC|DESC...}
示例:查询员工表和部门表
select * from emp,dept;
我们发线产生的记录数是56条,我们还会发现emp表是14条,dept表是4条,56正是emp表和dept表的记录数的乘积,我们称其为笛卡尔积。
如果多张表进行一起查询而且每张表的数据很大的话笛卡尔积就会变得非常大,对性能造成影响,想要去掉笛卡尔积我们需要关联查询。
再两张表中我们发现有一个共同的字段是depno,depno就是两张表的关联的字段,我们可以使用这个字段来做限制条件,两张表的关联查询字段一般是其中一张表的主键,另一张表的外键。
select * from emp,dept where emp.deptno = dept.deptno;
关联之后我们发线数据条数是14条,不再是56条。
多表查询我们可以为每一张表起一个别名
select * from emp e, dept d where e.deptno = d.deptno;
示例:查询出雇员的编号,姓名,部门的编号和名称,地址
select e.empno, e.ename, d.deptno, d.dname, d.loc
from emp e, dept d
where e.deptno = d.deptno;
示例:查询出每个员工的上级领导
分析:emp表中的mgr字段是当前雇员的上级领导的编号,所以该字段对emp表产生了自身关联,剋使用mgr字段和empno来关联
select e.empno, e.ename, e2.empno,e2.ename
from emp e, emp e2
where e.mgr = e2.empno;
示例:再上一个例子的基础上查询该员工的部门名称
分析:只要再上一个例子基础上再加一张表的关联,使用deptno来做关联字段即可
select e.empno, e.ename, e1.empno, e1.ename, d.dname
from emp e, emp e1, dept d
where e.mgr = e1.empno and e.deptno=d.deptno;
示例:查询出每个员工编号,姓名,部门名称,工资等级和他的上级领导的姓名,工资,等级
select e.empno,e.ename, decode(s.grade,
1,'一级',
2,'二级',
3,'三级',
4,'四级',
5,'五级') grade,
d.dname,e1.empno, e1.ename,
decode(s1.grade,
1,'一级',
2,'二级',
3,'三级',
4,'四级',
5,'五级')grade
from emp e, emp e1, dept d, salgrade s, salgrade s1
where e.mgr = e1.empno
and e.deptno = d.deptno
and e.sal between s.losal and s.hisal
and e1.sal between s1.losal and s1.hisal;
外连接(左右连接)
- 右连接
当我们在做基本连接查询的时候,查询出所有的部门下的员工,我们发线编号为40的部门下没有员工,但是要求把该部门也展示出来,上面的查询时办不到的。
select e.empno, e.ename, d.deptno, d.dname
from emp e, dept d
where e.deptno(+) = d.deptno;
使用(+)表示左连接或者右连接。
示例:查询出所有员工的上级领导
分析:我们使用以前的做法发现KING的没有上级领导,需要使用外连接把他查询出来
select e.empno, e.ename, m.empno, m.ename
from emp e, emp m
where e.mgr = m.empno(+);
使用left join实现:
select e.deptno, e.ename, m.deptno, m.ename
from emp e left join emp m
on e.mgr = m.empno;
(+)这种形式时Oracle数据库独有的,所以left join或right join 也需要了解。
层次查询(树型结构查询)
层次化查询,即树型结构查询,是SQL中经常用到的功能之一,通常由根节点,父节点,子节点,叶节点组成,其语法如下:
SELECT [LEVEL] ,column,expression,...
FROM table_name
[WHERE where_clause]
[[START WITH start_condition] [CONNECT BY PRIOR prior_condition]];
- LEVEL:
为伪列,用于表示树的层次 - start_condition:
层次化查询的起始条件 - prior_condition:
定义父节点和子节点之间的关系
示例:查询所有员工的上级领导
分析:
起始条件为King没有上级,子节点与父节点的关系为:子节点的mgr=父节点的empno
select level, empno, ename, mgr
from emp
start with mgr is null
connect by prior empno = mgr
order by 1;