zoukankan      html  css  js  c++  java
  • Oracle之数据操作__子查询

    子查询

     子查询是一个完整的查询语句之中,嵌套若干个不同功能的小查询,从而一起完成查询。

       复杂查询 = 限定查询 +多表查询 + 统计查询 + 子查询

     子查询可以返回的数据类型一共分为四种:

    子查询可以返回的数据类型一共分为四种:
            单行单列:返回的是一个具体列的内容,可以理解为一个单值数据
            单行多列:返回一行数据中多个列的内容
            多行单列:返回多行记录之中同一列的内容,相当于给出了一个操作范围
            多行多列:查询返回的结果是一张临时表
    #WHERE子句:  此时子查询返回的结果一般都是单行单列,单行多列,多行多列
    #HAVING子句: 此时子查询返回的都是单行单列数据,同时为了使用统计函数操作
    #FROM子句:   此时子查询返回的结果一般都是多行多列,可以按照一张数据表(临时表)的形式操作

    1. 查询公司之中工资最低的雇员的完整信息

    SELECT * FROM emp WHERE sal=(select min(sal) from emp);

    二 在WHERE子句中使用子查询

    A.返回单行单列

     1. 查询基本工资比“二宝”低的全部雇员信息

    SELECT * FROM emp WHERE sal<(select sal from emp where ename='二宝');
    View Code

    2. 查询基本工资高于公司平均薪金的全部雇员信息

    SELECT * FROM emp WHERE sal>(select avg(sal) from emp);
    View Code

    3.查询出与‘’李四‘’从事同一份工作,并且基本工资高于雇员7521(不包括李四)的全部雇员信息

    SELECT * FROM emp
    WHERE job=(select job from emp where ename='李四')
    AND   sal>(select sal from emp where empno=7521)
    AND   ename<>'李四';
    View Code

         

    B. 返回单行多列 

    1. 查询与‘风清扬’从事同一份工作且工资相同的雇员信息(不包括风清扬)

    SELECT * FROM emp
    WHERE (job,sal)=(select job,sal from emp where ename='风清扬')
    AND ename<>'风清扬';
    View Code

    2. 查询与雇员7749从事同一工作且领导相同的全部信息

    SELECT * FROM emp 
    WHERE (job,mgr)=(SELECT job,mgr FROM emp WHERE empno=7749);
    View Code

    3. 查询与‘’李四‘从事同一工作且在同一年雇佣的全部雇员信息’(包括李四)

    SELECT * FROM emp
    WHERE (job,TO_CHAR(hiredate,'yyyy'))=(
                 SELECT job,TO_CHAR(hiredate,'yyyy') FROM emp WHERE ename='李四');
    View Code

    C. 返回多行单列数据

      主要使用 IN,ANY,ALL

    ## IN

    1.查询出与每个部门中最低工资的全部信息

    SELECT * FROM emp 
    WHERE sal IN (select min(sal) from emp group by did);
    View Code

    注意:关于null的问题,如果在IN之中子查询返回的数据有null,那么不会有影响。如果在 NOT IN 之中子查询返回的数据有null,那么就不会有任何数据返回。

    select * from emp where empno not in ( select mgr from emp );

        

    ## ANY

            

    1.操作准备:首先找出每个部门经理的最低工资(考虑一个部门可能有多个经理)

    SELECT min(sal) FROM emp WHERE job='MANAGER' group by did;

              

    1.1. 然后:

    SELECT sal FROM emp 
    WHERE sal=ANY(
        select min(sal) from emp where job='MANAGER' group by did
    );

                      

    1.2. 发现1,1.1的结果,一样

    2.  >ANY操作(最小的是 1111)

    SELECT * FROM emp
    WHERE sal>ANY(select min(sal) from emp where job='MANAGER' group by did);

             

     D. exists结构

        空数据判断,在SQL之中,提供了 exists结构用于判断子查询是否有数据返回。如果子查询有数据返回,则exists结构返回 true,否则为 false

    1.

    SELECT * FROM emp 
    WHERE  exists (
        select * from emp where empno=9999
    );

               

    #由于不存在 9999 编号的雇员,所以在这里 exists()判断返回就是false,就不会有结果返回

    2.使用 not

    select * from emp
    where not exists(
        select * from emp where empno=9999
    );

    三 在HAVING子句中使用子查询

        HAVING 一定是结合GROUP BY 子句一起使用的,其主要的目的是进行分组后数据再次过滤,而且与WHERE子句不同的是,HAVING是在分组后,可以使用统计函数。

    1.查询部门编号,雇员人数,平均工资,并且要求部门的平均工资高于公司平均工资

    SELECT did,count(empno),avg(sal) FROM emp
    GROUP BY did
    HAVING avg(sal)>(select avg(sal) from emp);
    View Code

    2. 查询出每个部门平均工资最高的部门名称及平均工资

    select d.dname,round(avg(e.sal),2)
    from emp e,dept d
    where e.did=d.did
    group by d.dname 
    having avg(sal)=(select max(avg(sal)) from emp group by did);
    View Code

    四 在FROM子句中使用子查询

    1. 要求查询出每个部门的编号,名称,位置,部门人数,平均工资

    SELECT d.did,d.dname,d.loc,temp.人数 ,temp.平均工资
    FROM dept d,(select did di,COUNT(empno) 人数,ROUND(avg(sal),2) 平均工资 FROM emp GROUP BY did) temp
    WHERE d.did=temp.di(+);
    View Code

                          

     2. 查询出所有在 '公关部 '部门工作的员工的编号,姓名,基本工资,奖金,职位,雇佣日期,部门的最高和最低工资

    select e.empno,e.ename,e.sal,e.comm,e.job,e.hiredate,temp.max,temp.min
    from emp e,(select did dd,MAX(sal) max,MIN(sal) min from emp GROUP BY did) temp 
    WHERE e.did=(select did from dept where dname='公关部') AND e.did=temp.dd;
    View Code

              

     #提示:(select did dd,MAX(sal) max,MIN(sal) min from emp GROUP BY did) temp ---> 子查询负责统计信息,使用temp表示临时的统计结果

    3. 查询出所有薪金高于公司平均薪金的员工编号,姓名,基本工资,职位,雇佣日期,所在部门名称,位置,上级领导名称,公司的工资等级,部门人数,平均工资,平均服务年限

    SELECT e.empno,e.ename,e.sal,e.job,e.hiredate,d.loc,m.ename
    FROM emp e,dept d,emp m,salgrade s,(select did dd,count(empno) count,
                  round(avg(months_between(sysdate,hiredate)/12),1) avgyear from emp group by did) temp
    WHERE e.sal>(select avg(sal) from emp) 
    AND e.did=d.did
    AND e.mgr=m.empno(+)
    AND e.sal BETWEEN s.losal AND s.hisal
    AND e.did=temp.dd;
    View Code

    4. 查询薪金比 ‘张三’ 或 ‘如花’ 多的所有员工的编号,姓名,基本工资,部门名称,其领导姓名,部门人数

    SELECT e.empno,e.ename,e.sal,d.dname,m.ename 领导姓名,temp.count
    FROM emp e,dept d,emp m,(select did dd,count(empno) count from emp group by did) temp
    WHERE e.sal>ANY(select sal from emp where ename in('张三','如花'))
    AND e.did=d.did 
    AND e.mgr=m.empno(+)
    AND temp.dd=d.did
    AND e.ename NOT IN('张三','如花');
    View Code

     5. 列出公司各个部门的经理(假设每个部门只有一个经理,job为 “MANAGER”)的姓名,薪金,部门名称,部门人数,部门平均工资

    SELECT e.ename,e.sal,d.dname,temp.count,temp.avg
    FROM emp e,dept d,(select did dd,count(empno) count,round(avg(sal),2) avg from emp group by did) temp
    WHERE job='MANAGER'
    AND e.did=d.did
    AND e.did=temp.dd;
    View Code

    五 在SELECT子句中使用子查询(了解)

     1.查询出公司每个部门的编号,名称,位置,部门人数,平均工资

    SELECT did,dname,loc,
        (select count(empno) from emp where did=d.did group by did) count,
        (select round(avg(empno),2) from emp where did=d.did group by did) avg
    FROM dept d;
    View Code

    2.不分组也可以

    SELECT did,dname,loc,
        (select count(empno) from emp where did=d.did ) count,
        (select round(avg(empno),2) from emp where did=d.did ) avg
    FROM dept d;
    View Code

                                        

    六 WITH子句

        临时表实际上就是一个查询结果,如果一个查询结果返回的是多行多列。那么就可以将其定义在FROM字句之中,表示为一张临时表。除了在FROM子句之中出现临时表之外,也可以利用WITH子句直接定义临时表,就可以绕开了FROM子句。

    1.使用WITH子句将emp表中的数据定义为临时表

    WITH e AS(select * from emp)
    SELECT * FROM e;

    2.查询每个部门的编号,名称,位置,部门平均工资,人数

    WITH e AS (select did dd,round(avg(sal),2) avg,count(sal) count from emp group by did)
    SELECT d.did,d.dname,d.loc,e.count,e.avg FROM e,dept d
    WHERE e.dd(+)=d.did;
    View Code

    3.查询每个部门工资最高的雇员编号,姓名,职位,雇用日期,工资,部门编号,部门名称,显示的结果按照部门编号进行排序

    WITH e AS (select did dd,max(sal) max from emp group by did)
    SELECT em.empno,em.ename,em.job,em.hiredate,em.sal,d.did,d.dname
    FROM e,emp em,dept d
    WHERE e.dd=em.did
    AND em.sal=e.max
    AND e.dd=d.did
    ORDER BY d.did;
    View Code

                                      

  • 相关阅读:
    SQL Server学习之路:建立数据库、建立表
    tomcat访问的重定向问题
    PAT A1107——并查集
    ^-^
    JSON.parse()和JSON.stringify()的用法
    Android——ViewHolder的作用与用法
    题解-Atcoder_agc005D ~K Perm Counting
    题解-bzoj2560 串珠子
    题解-Codeforces710F String Set Queries
    游记-NOIP2018
  • 原文地址:https://www.cnblogs.com/zhaochangbo/p/8407332.html
Copyright © 2011-2022 走看看