Oracle多表关联

1.语法多表关联

1.1笛卡尔积

select * from emp,dept;

1.2等值连接

select e.ename,e.deptno,d.dname from emp e,dept d where e.deptno = d.deptno

1.3不等值连接

select e.ename,e.sal,sg.grade from emp e,salgrade sg where e.sal >= sg.losal and e.asl <=sg.hisal

1.4外连接

左外连接:左边的表作为主表,右边表作为从表,主表数据都显示,从表数据没有,用null填充,用“+”号表示

select * from dept d,emp e where d.deptno = e.deptno(+)

右外连接:右边的表作为主表,左边表作为从表,主表数据都显示,从表数据没有,用null填充,用“+”号表示

select * from dept d,emp e where d.deptno(+) = e.deptno

1.5自连接

查询每个雇员的上级领导

select e.ename “雇员”,m.ename "领导" from emp e, emp m where e.mgr = m.empno

优化King

select e.ename "雇员" ,nvl(m.ename,"boss")"领导" from emp e,emp m where e.mgr = m.empno(+)

1.6多余的两张表的连接

如果有多张表参与查询,先把t1*t2笛卡尔积得到一个大表T1,再把笛卡尔积得到一个另外的大表T2,以此类推

查询SCO%T管理员最终都是两种表的查询

select e.ename,m.ename,sg.grade from emp e,emp m,salgrade sg

where e.mgr = m.empno and(m.sal between sg.losal and sg.hisal) and e.ename='SCO%T'

 

查询雇员Scott所在部门名称和薪资等级

select e.,d.,sg.* from emp e,dept d,salgrade sg where e.deptno = d.deptno and e.sal between sg.losal and sg.hisal and e.ename = 'SCO%T'

2.语法多表关联

(1)表的过滤条件和表的连接条件混合在一起,维护麻烦

(2)数据库的数据适合变化,根据where子句的执行规则,SQL语言也会发生相应变化,给维护造成一定成本

2.1笛卡尔积

select * from dept d cross join emp e

2.2自然连接

NATURAL JOIN子句基于两个表中列名完全相同的列产生连接

【1】两个表中有相同字段名

【2】数据类型相同

【3】从两个表中选出连接列的值相等的所有行

select * from dept d natural join emp e

自然连接最优的使用场景是:主外键关系且主外键字段只有一个

Using关键字,主要用于指定字段连接字段

【1】按照指定的字段连接两张表

【2】选指定字段值相同的数据行

自然连接的条件是基于表中所有同名列的等值连接,为了设置任意的连接条件或者指定连接的列,需要使用ON子句连个表的关联用关键字join,默认内连接语法

select filed1,fild2,... from table1 join table2 on condition1

3.子查询

SQL查询是可以嵌套的,一个查询可以作为另外一个查询的条件,表

select select_list from table where expr operator(select select_list from table)

3.1单行子查询:当子查询有单行时,可以取单行中一个字段形成单个值用于条件比较

查询雇员其薪资在雇员平均薪资以上

【1】查询员工的平均薪资

select avg(e.sal)"AVGSAL" from emp e

【2】查询满足条件的雇员

select * from emp e where e.sal > (select avg(e.sal) "AVGSAL" from emp e)

3.2多行子查询:查在雇员中有哪些人是管理者

【1】查询管理者

select distinct e.mgr from emp e where e.mgr is not null

【2】查询指定列表的信息

select e.* from emp e where e.empto in(select distinct e.mgr from emp e where e.mgr is not null)

多行子查询返回的结果可以作为表使用,通常结合in、some/any、all、exists

3.3from后的子查询

每个部门平均薪水的等级

【1】部门平均薪资

select e.deptno,avg(e.sal)"AVGSAL" from emp e group by e.deptno

【2】求等级

select vt0.deptno,vt0.avgsal,sg.grade from (select e.deptno,avg(e.sal)"AVGSAL" from emp e group by e.deptno)VT0,salgrade sg where vt0.avgsal between sg.losal and sg.hisal

3.4TOP-N:把select得到的数据集提取前n条数

rownum:表示对查询的数据集记录的编号,从1开始

---查询前10名雇员

select e.*,rownum from emp e where rownum <=10

select vt0.*,rownum from (select e. * from emp e order by e.sal desc) VT0 where rownum <= 10

【1】order by一定在整个结果集出现后执行

【2】rownum在结果集出现后才有编号

 

 

原文地址:https://www.cnblogs.com/Hiramunderneath/p/15424413.html