培训第5天----Oracle的分页查询和子查询

    在学习Oracle的分页查询和子查询之前,我们先明确一下 static 和final关键字的用法。

一. static(静态的)关键字:

    只能用于修饰成员方法和成员变量。

    被static修饰的成员变量变成了类变量,随着类的创建而创建,随着类的消失而消失。而普通的成员变量是随着

对象的创建而创建,随着对象的销毁而消失。

    被static修饰的成员方法变成了类方法,可以直接通过类名来调用,和.class一样存在于方法区中。(方法区中的

方法和属性会是唯一的)

    非静态的成员方法和成员变量只能通过对象来调用,例如:对象.方法。但是静态的成员方法和成员变量可以通过

类名来调用(尽量用类名调用,不要创建对象)。

    被修饰的成员有以下特点:

    1)随着类的加载而加载。

    2)优先于对象存在。

    3)被所有对象所共享(所被修饰的成员方法和成员变量会在类加载的时候加载到方法区,

                                        成为公共的全局方法和全局变量,比较节约空间)。

    4)可以直接用类名来调用。

    注意事项:

    1)静态方法只能访问静态的成员变量而不能访问非静态的成员变量,为什么?

             这是因为静态方法和静态变量在加载类的时候就被加载到方法区中,所以可以调用。但

        是成员变量是在创建对象的时候进行加载的,非静态方法是在对象调用的时候进行加载的,所以当静态方法

存在的时候, 对象没有创建,普通变量并不存在。

    2)非静态方法可以访问静态的成员变量,为什么?

             这是因为要想调用非静态方法必须要用对象来调用,既然对象已经被创建,在对象调用

非静态方法的时候会被加载。所以非静态方法和成员变量也被创建,所以可以访问。 (图片中所

出现的x 是因为在静态方法中,不能引用当前类的对象。)

培训第5天----Oracle的分页查询和子查询

        静态方法只能访问静态方法和静态成员变量,而非静态方法既能访问静态方法也能访问非静态

方法。非静态方法在能访问静态成员变量的同时,也能访问非静态的成员变量。

二.final(最终关键字):

    在Java中,final可以修饰类,属性(成员变量和局部变量)和方法。

    1)修饰类:说明这个类是最终类,不能被继承。

    2)修饰变量:修饰基本类型变量时,则数据一旦被确定就不能改变。当修饰引用类型变量时,其引

         用不能只想其他的对象,但是其对象内的属性可以改变。

         final修饰的变量,是常量,一旦被赋值,就不能被更改。

    3)修饰方法:表示这个方法是最终方法,不能被子类重写。

=======================================================================

    现在我们来进入我们今天的正题,Oracle的分页查询和子查询。

    在查询时,如果查询过程中逻辑很明确会减少java中的代码。例如:
          目的:查询emp表中有多少人
          select * from emp --> java(ResultSet) --> 解析结果集合 --> java构建计数器 --> 统计计数器总数

          select count(*) from emp --> java(ResultSet)-->解析结果集合 --> 直接获取结果

    Mysql和Oracle分页查询的方式是不一样的。

          Mysql 的pagination  (分页查询)  利用的是limit关键字进行区域上的限制。

          Oracle 的 pagination  (分页查询)  利用的是子查询+伪列进行形成的真分页查询。


            -- rownum  (伪列)
            select  e.*,rownum

                   from emp e

            查询结果会有一个rownum列,用来记录当前的行数。

            -- 查询前3条数据
            select e.*,rownum
                   from emp e

                        where rownum <= 3

            这样是可以的,因为在查询的时候必须是从伪列的第一列的相对位置开始的,rownum<3

中包含rownum=1。

            -- 查询4-6条数据
            select e.*,rownum
                   from emp e

                        where rownum > 3 and rownum<6

            这样是不可以的,所要查询的数据中,没有rownum=1的情况。

            -- 伪劣必须含有rownum 为 1的情况
            -- 如何固定住伪列,利用子查询进行固定伪列
            -- pageNum : 2,pageSize : 3
               select * 
                    from  (select e.*,rownum rm from emp e where rownum <= 6)
                        where rm > 3

            -- pageNum :3,pageSize : 3
             select * 
                    from  (select e.*,rownum rm from emp e where rownum <= 9)
                        where rm > 6


            -- 结论分页查询公式
              select * 
                   from 
            -- 子查询固定伪列 即rownum = 1的情况 
               (select e.*,rownum rm from emp e where rownum <= pageNum*pageSize)
                        where rm > (pageNum-1)*pageSize
            
         -- sum()计算总和的函数 
         -- 如何将null值替换成0数值
         -- nvl()替换空值函数         

             select e.sal,e.comm,(e.sal+nvl(e.comm,0)) from emp e   

            在Oracle中,在和null进行数学运算时,生成的结果都为空。所以要用到nvl()函数。       

         -- 查询表达式
             select empno      --  第五步
                    from emp    --   第一步
                          where empno > 5   -- 第二步
                          group by empno --  第三步
                          having sum(sal) > 2000  -- 第四步
                          order by empno desc -- 第六步     
             
        -- in() 函数 通常用于业务中的批量删除,修改数据
        -- 对比in() 与  between and的区别
        -- switch方式定值判断

           select * from emp where emp.empno in(7566,7698,7782)      显示括号内存在的empno号

        -- between左右区间范围(包含区间值)
           select * from emp where emp.empno between 7566 and 7782    显示区间内存在的empno号


        -- any(some)  和 all
        -- any(some)就查询结果而言没有区别,满足其中一个条件即可
        -- all 必须满足all中所有条件才可以得到结果
           select * 
                  from emp
                           where emp.empno = all(7566)  
            all表示必须满足括号内的所有。
           select * 
                  from emp
                           where emp.empno in (7566,7698,7782) 


        select deptno ,ename,sal
                   from emp 
                        where sal =
                                   any (select sal from emp where deptno =10)  
                                   and deptno !=10

        any表示满足括号内的任意一个。

        join on:join的意思就是两个表联查,而on就相当于where 代表查询条件。


1.显示所有雇员的姓名、工作和薪金,
             按工作的降序排序,而工作按薪金排序。
  select *
          from emp e
               order by e.job desc,e.sal asc          
             
             
2.不准用组函数,求薪水的最高值
     select * from emp e2
            where e2.sal >= all(select sal from emp e)


 
3.求平均薪水最高的部门的部门编号
    select t2.dno,t1.maxavgsal
            from 
      (
            select max(avgsal) maxavgsal
                   from (
                        select avg(e.sal)avgsal,e.deptno dno
                           from emp e group by e.deptno
                         )
       ) t1
       join 
       (
            select avg(e.sal)avgsal,e.deptno dno
                   from emp e group by e.deptno
       ) t2 
       on t1.maxavgsal = t2.avgsal
4.求平均薪水最高的部门的部门名字
       select  t1.maxavgsal, t2.t2dname
          from 
       (
            select max(avgsal) maxavgsal
                   from (
                        select avg(e.sal)avgsal,e.deptno dno
                           from emp e group by e.deptno
                         )
       ) t1            
         join          
       (
        select avg(e.sal) t2avgsal,d.dname t2dname 
          from emp e join dept d on e.deptno = d.deptno
               group by d.dname 
       )t2
          
        on t1.maxavgsal = t2.t2avgsal       
5.求比普通员工的最高薪水还要高的经理人名称
   
   select * from emp m 
          where m.job = 'MANAGER'
                and m.sal > (select max(e.sal) from emp e where e.job = 'CLERK')