第七章子查询课堂笔记和练习

– 子查询
1.子查询(内部查询)优先于主查询(外部查询)执行
2.子查询的结果被主查询使用
– 单行子查询

    --  查询出比JONES工资高的其他雇员
    select ename
      from emp
     where sal > (select sal from emp where ename = 'JONES');

– 注意:查询的值需在表中存在,如输入ename = ‘JONEs’是没有数据返回的,
– 因为’JONEs’在ename列中不存在
– 列名对大小写不敏感,而列值对大小写敏感

    --  显示和雇员7369从事相同工作并且工资大于雇员7876的雇员的姓名和工作
    select ename, job
      from emp
     where job = (select job from emp where empno = 7369)
       and sal > (select sal from emp where empno = 7876);

– 子查询中使用组函数

    --  查询工资最低的员工姓名,岗位及工资
    select ename, job, sal from emp where sal = (select min(sal) from emp);

– 注意在where中与分组的子查询比较将产生错误

--  查询每个部门的最低工资员工信息
    select * from emp
             where sal = (select min(sal) from emp group by deptno);
    --  错误,单行运算符与多行子查询不匹配
    --  应使用having子句

– 在having子句中使用子查询

    --  查询部门最低工资比20部门最低工资高的部门编号及最低工资
    select deptno, min(sal)
      from emp
     group by deptno
    having min(sal) > (select min(sal) from emp where deptno = 20);

    --  查询哪个部门的员工人数 高于各部门平均人数。
    select deptno, count(empno)
      from emp
     group by deptno
    having count(empno) > 
           (select avg(count(empno)) from emp group by deptno);

– 多行子查询:返回多行一列的值,使用多行运算符:in any all

  • in 满足其中一个条件

        --  查询是经理的员工姓名,工资
            select ename, sal
              from emp
             where empno in
                   (select distinct mgr from emp where mgr is not null);
    
  • any 满足其中一个条件

    --  查询是经理的员工姓名,工资
        select ename, sal
          from emp
         where empno = any
         (select distinct mgr from emp where mgr is not null);
         --  =any 功能与in一样
    
    --  查询部门编号不为10,且工资比10部门任意一名员工工资高的员工编号,姓名,职位,
    ->  工资。
        select empno, ename, job, sal
          from emp
         where sal > any (select sal from emp where deptno = 10)
           and deptno <> 10;
    
    --  查询部门编号不为10,且工资比10部门任意一名工资低的员工编号,姓名,职位,工资。
        select empno, ename, job, sal
          from emp
         where sal < any (select sal from emp where deptno = 10)
           and deptno <> 10;   
    
  • all 满足其中所有条件

    --  查询部门编号不为10,且工资比10部门所有员工工资高的员工编号,姓名,职位,工资。
        select empno, ename, job, sal
          from emp
         where sal > all (select sal from emp where deptno = 10)
           and deptno <> 10;
    
    --  查询部门编号不为10,且工资比10部门所有员工工资低的员工编号,姓名,职位,工资。
        select empno, ename, job, sal
          from emp
         where sal < all (select sal from emp where deptno = 10)
           and deptno <> 10;
    
    --  查询部门编号不为10,且工资和10部门所有员工工资相等的员工编号,姓名,
    ->  职位,工资。
    --  = all 一般无意义
        select empno, ename, job, sal
          from emp
         where sal = all (select sal from emp where deptno = 10)
           and deptno <> 10;
    

    – 多列子查询

    成对比较
    --  查询出和1981年入职的任意一个员工的部门和职位!!完全相同!!员工姓名、部门、职位、
    ->  入职日期,
    ->  不包括1981年入职员工。  
        select ename, deptno, job, hiredate
          from emp
         where (deptno, job) in  --列名之间逗号','隔开,所有列名用()扩号修饰
               (select deptno, job
                  from emp
                 where to_char(hiredate, 'YYYY') = '1981')
           and to_char(hiredate, 'YYYY') <> '1981';
    
       不成对比较   
       --  查询出和1981年入职的任意一个员工的部门!!或职位!!相同员工姓名、部门、职位、
       ->  入职日期,
       ->  不包括1981年入职员工。  不成对比较
           select ename, deptno, job, hiredate
             from emp
            where (deptno in
                  (select deptno from emp where to_char(hiredate, 'YYYY') = '1981') 
                  or job in
                  (select job from emp where to_char(hiredate, 'YYYY') = '1981'))
                               and to_char(hiredate, 'YYYY') <> '1981';
    

    – 子查询中的空值(null)

       --  注意:子查询的结果中有一条空值,这条空值导致主查询没有记录返回。
       ->  这是因为所有的条件和空值比较结果都是空值。
       --  因此无论什么时候只要空值有可能成为子查询结果集合中的一部分,
       ->  就不能使用NOT IN 运算符。
           select ename
            from  emp
           where  empno not in
                  (select distinct mgr from emp);
    

    – 在from字句中使用子查询
    一般遇到要跟自己比较的都用子查询在from语句中的使用

       --  查询比自己部门平均工资高的员工姓名,工资,部门编号,部门平均工资
          select a.ename, a.sal, a.deptno, b.salavg
            from emp a,
                 (select deptno, avg(sal) salavg from emp group by deptno) b
           where a.deptno = b.deptno
             and a.sal > b.salavg;
    

    – rownum 伪列: 永远从1开始,只能使用 < 、<=,不能使用>,=,>=,between..and区间运算做比较运算

       select  rownum,empno, ename, job
         from  emp
        where rownum <= 5;
    
      --rownum可以与order by结合使用
      select rownum,e.* from emp e order by rownum desc;
    

    – rowid 伪列,物理存在,唯一标识每一行数据,可以通过rowid修改数据或删除数据

       select rowid,e.* from emp e where rowid='AAAR3sAAEAAAACXAAH';
    

    – top-n:查询某列前n条数据,通过rownum伪列来查询
    – !!!不是关键字

    --  查询员工表中前五名薪资最【高】的员工信息
        select rownum,e.* 
          from (select * from emp  order by sal desc) e 
         where rownum <= 5;
    
    --  查询员工表中前五名薪资最【低】的员工信息
        select rownum,e.* 
          from (select * from emp order by sal asc) e 
         where rownum <= 5
    

    – 分页查询
    – 结合子查询在from子句中的使用

    已知:每页显示5条,当前页数1  
    1  1-5
    2  6-10
    3  11-15
    4  16-20
    开始索引:(当前页码*每页显示条数)-每页显示条数 + 1 = (当前页码-1)*每页显示条数+1
    结束索引:当前页码*每页显示条数
    
    select rownum,e.* from emp e where rownum <= 5; --第一页
    
    select * from (select rownum rn,e.* from emp e where rownum <=10) where rn>=6;
     --第二页 效率高,先选择从1到需要查询的最大值之间的数据,再按要查的页数进行筛选
    
    select * from (select rownum rn,e.* from emp e) where rn<=10 and rn>=6;        
    --第二页 效率低,直接查出所有数据,再进行最小值与最大值的筛选
    
    select * from (select rownum rn,e.* from emp e where rownum <=15) where rn>=11;
     --第三页
    select * from (select rownum rn,e.* from emp e) where rn<=15 and rn>=11;        
    --第三页
    

    –&表示一个变量,beginIndex、endIndex分别为变量名称,可自定义

    select * 
      from (select rownum rn,e.* from emp e where rownum <=&endIndex) 
     where rn>=&beginIndex;
    

    –分页排序
    在子查询外再嵌套一层子查询,用于查询后数据排序

    • 即rownum是按照查询结果的顺序生成的,若直接排序将打乱其顺序
      故需要在外层套一层子查询,将排好序的数据重新生成rownum伪列

      select *
        from (select rownum rn, e.*
                from (select * from emp order by sal) e
               where rownum <= 10) e2
       where rn >= 6
      

猜你喜欢

转载自blog.csdn.net/bb_code_exchange/article/details/81325979