十一、Oracle学习笔记:高级关联查询

一、关联查询基础
    1.意义:有时候所需要的数据需要依赖多个表,可能会在两个表或多个表中这个时候需要操作多个表,才可以得到需要的数据,而这种查询 就叫做关联查询。

--练习:查看部门表和员工表的信息
  select * from emp,dept;                              --连接查询,会出现笛卡尔积,没有意义
  select * from emp,dept where emp.deptno=dept.deptno; --等值连接

    2.连接查询:from子句中含有多个表,显示出来表中的所有数据
    3.笛卡尔积:当做多个表的连接查询时,没有where子句进行条件限制,比如表A和表B进行连接查询,那么就会出现rowA*rowB条数据组合。通常笛卡尔查询是没有意义的,需要避免。
    4.等值连接:通常两个表中某些字段是有关系的。而在查询的时候,我们使用这些有关系的字段进行等值查询,也就是相等的组合成一条记录。

二、关联查询详解
1.内连接:两张表使用 join on 进行关联查询,进行条件限制,显示出来的数据都是符合条件的          

--格式:table_A join  table_B on (条件)
--练习:使用内连接查询员工表和部门表的信息
  select * from emp inner join dept on (emp.deptno=dept.deptno);

2.外连接:当需求为要查询一张表中的所有数据,另外一张表满足条件的数据时,表A全部显示,表B满足条件显示这种情况要使用外连接
     驱动表(主):要显示全部数据的那张表, 从动表(副):满足条件数据的那张表
(1)左外连接:

--格式:table_A left [outer] join table_B on 条件
--A是驱动表,B是从表
--练习:查询所有员工信息及员工所在部门信息
  select emp.empno,emp.ename,emp.job,dept.deptno,dept.dname,dept.loc from emp left join dept on emp.deptno=dept.deptno;
  or
  select emp.empno,emp.ename,emp.job,dept.deptno,dept.dname,dept.loc from emp,dept where emp.deptno=dept.deptno(+);

(2)右外连接:

--格式:table_A right [outer] join table_B on 条件
--B是驱动表,A是从表
--练习:查询所有的部门信息以及部门所包含的员工信息
select emp.empno,emp.ename,emp.job,dept.deptno,dept.dname,dept.loc from emp right join dept on emp.deptno=dept.deptno;
or
select emp.empno,emp.ename,emp.job,dept.deptno,dept.dname,dept.loc from emp,dept where emp.deptno(+)=dept.deptno;
       

(3)全外连接:两张表中满足条件的数据显示,不满足条件的数据也都显示                

--格式:table_A full [outer] join table_B on 条件
  select emp.empno,emp.ename,emp.job,dept.deptno,dept.dname,dept.loc from emp full join dept on emp.deptno=dept.deptno;

3.自连接查询:多个表是同一张表时,就叫自连接,此时表内的某些字段一定会有关系            

--格式:table_A a join table_A b on 条件   
--练习:查询员工姓名和职位,以及其领导的姓名和工资
  select p.ename,p.job,e.ename,e.sal from emp e join emp p on e.empno=p.mgr;       

           
4.子查询:当某一个查询语句中所需要的数据,表中没有直接体现,而是通过先执行另外一个查询语句查询出来的结果。先执行的查询语句就是子查询,被嵌入的查询语句是父查询

(1)子查询在where子句中,作为条件的数据需要一次子查询  

--返回的数据一行一列,where 返回的数据 '='连接
--返回的数据多行一列,where 返回的数据用 'in' 连接
--返回的数据多行多列。         
--练习:查询工资大于jones这个人工资的所有员工信息
  select * from emp where sal>(select sal from emp where ename='JONES');
--练习:查询与jones同部门的其他员工信息
  select * from emp where deptno=(select deptno from emp where lower(ename)='jones') and ename!='JONES';           
--练习:查询SMITH和ALLEN这两个人同部门的其他员工信息
  select * from emp where deptno in (select deptno from emp where ename in('SMITH','ALLEN')) and ename not in('SMITH','ALLEN');   

(2)子查询在having子句中

--练习:查询部门平均工资大于10号部门平均工资的部门号及其平均工资
  select deptno,avg(sal) from emp group by deptno having avg(sal)>(select avg(nvl(sal,0)) from emp where deptno=10);
--练习:查询职位人数大于'CLERK'这个职位人数的职位
  select job,max(sal),sum(sal) from emp group by job having count(*)<(select count(*) from emp where job='CLERK');
    


(3)子查询在from子句中, 一个查询语句后,还想查询出来的数据的基础上再查询

--注意:当子查询在from子句中,相当于一张没有名字的表,这样的表叫行内视图(view)也叫匿名视图
--练习:查询部门的平均工资大于2000的部门信息和员工信息
  select * from dept,emp where dept.deptno=emp.deptno and dept.deptno in (select deptno from emp group by deptno having avg(sal)>2000));
  select e.*,d.* from emp e,dept d,(select deptno from emp group by deptno having avg(sal)>2000) f where e.deptno=d.deptno and d.deptno=f.deptno;
--练习:查询员工工资大于本部门的平均工资的员工信息
  select * from emp a where sal>(select avg(sal) from emp b where a.deptno=b.deptno);
  select * from emp e,(select deptno,avg(sal) avg_sal from emp group by deptno) f where e.deptno=f.deptno and e.sal>f.avg_sal;
--练习:查询部门的平均工资其员工的信息
  select e.*,avg_sal from emp e,(select deptno,avg(sal) avg_sal from emp group by deptno) f where e.deptno=f.deptno order by e.deptno;

(4)子查询在select子句中(相当于外连接的一种写法)

  select e.ename,e.job,(select d.dname from dept d where d.deptno=e.deptno) 部门名称 from emp e;

三、练习

--1:查询和JONES同职位的员工
  select * from emp where job=(select job from emp where upper(ename)='JONES');
--2:查询月薪比整个公司的平均月薪高的员工
  select * from emp where sal>(select avg(nvl(sal,0)) from emp);
--3:查询部门中有SALESMAN但是职位不是SALESMAN的员工信息
  select * from emp where deptno in (select distinct deptno from emp where job='SALESMAN') and job!='SALESMAN';
--4:查询有员工的部门信息及其员工信息(内连接)
  select dept.*,emp.* from emp join dept on dept.deptno=emp.deptno; 
--5:查询所有部门以及员工的信息
  select dept.*,emp.* from emp right join dept on dept.deptno=emp.deptno; 
--6:查询公司的部门和员工信息
  select dept.*,emp.* from emp full join dept on dept.deptno=emp.deptno;
--7:查询工资大于10部门的所有员工工资的员工信息
  select * from emp where sal>all(select sal from emp where deptno=10);
--8:查询工资大于10部门中任意一个员工工资的其他部门员工信息
  select * from emp where sal>any(select sal from emp where deptno=10) and deptno!=10;
               

猜你喜欢

转载自blog.csdn.net/qq_38741971/article/details/81413302