zoukankan      html  css  js  c++  java
  • Oracle Sql优化之报表和数据仓库运算

    1.行转列:有两种写法,一种是case when end写法,另一种写法是pivot(oracle 11g新增)

    select job,
              sum(case deptno when 10 then sal end) as sal10,
              sum(case deptno when 20 then sal end) as sal20,
              sum(case deptno when 30 then sal end) as sal30,
              sum(sal) as allsal
    from emp
    group by job
    order by 1;
    select *  
    from (select job,sal,deptno from emp)
    pivot(sum(sal) as s for deptno in(10 as d10,20,30 as d30))
    order by 1;

    pivot的维护比case when end简洁,当增加一个统计属性时,只需增加一个sum函数。

    pivot一次只能实现一个属性的行专列,多个属性的行转列只能采用case when end

    执行计划:pivot在执行时,还是被翻译成了case when end.

    2.列转行:有两种写法,一种是union all,另一种是unpivot分析函数

    select10as deptno, deptno_10_ct as rc from test
    union all
    select '20' as deptno, deptno_20_ct as rc from test
    select * from test
    unpivot (rc for deptno in(deptno_10_ct,deptno_20_ct));

    union all 的执行计划显示需要两次全表扫描,而unpivot则只需一次

    当同时需要对两种属性进行转置时,可以进行如下处理

    select deptno,rc.sal
    from test
    unpivot include null(rc for deptno in(deptno_10_ct as 10,deptno_20_ct as 20))
    unpivot include null(sal for deptno1 in(deptno_10_s as 10,deptno_20_s as 20))
    where deptno =deptno1;

    需要注意:unpivot转置的列属性要一致;include null是当遇到空值时也转置,xxx for col in 默认所有列。

    2.分组显示中,抑制重复值的显示

    select case when lag(job) over(order by job,ename)=job then null else job end as fjob,ename as fename
    from emp1
    where deptno=20
    order by job,ename

    注意order by优先使用select 中别名.

    3.ntile函数,对数据按照指定数量进行分组优化

    select ntile(3) over(order by empno) as g,empno,ename,job
    from emp
    where job in ('MANAGER','CLERK');

    4.分组求和:按照某一属性或多个属性,分组求和之后,如何把求和的结果求一个总计

    select deptno,job,sum(sal)
    from emp
    group by rollup((deptno,job));

    采用group by的一个扩展 rollup函数。

    区分返回结果中哪些是小计,哪些是总计

    select case grouping(deptno) when 1 then '总计'  else to_char(deptno) end as code,
              case when grouping(deptno)=1 then null when grouping(job)=1 then '小计' else job end as gz,
              case when grouping(job)=1 then null when grouping(mgr)=1 then '小小计' else to_char(mgr) end as mmgr,
              max(case when empno in(7788,7654,7902) then empno end) as max_empno,
              sum(sal) as salsum
    from emp1
    group by rollup((deptno,job,mgr));

    分组后,实现数据的立方上下钻取,可以采用cube分析函数,也是group by的一个扩充

    select case grouping(deptno)|| grouping(job)
              when '00' then 'gdepjob'
              when '10' then 'gdep'
              when '01' then 'gjob'
              when '11' then 'gall' end as gelem,
             deptno,job,sum(sal) as allsal
    from emp
    group by cube(deptno,job)
    order by grouping(job) desc,grouping(deptno)desc, deptno asc;

    5.分析函数的,开窗的识别,range,row的区别

    select ename,sal,
              sum(sal) over(order by sal) as sal1,
              sum(sal) over(order by sal range between unbounded preceding and current row) as sal2,
              sum(sal) over(order by sal rows between unbounded preceding and current row) as sal3,
              sum(sal) over() as sal4,
              sum(sal) over(order by sal range between unbounded preceding and unbounded following) as sal5,
              sum(sal) over(order by sal rows between unbounded preceding and unbounded following) as sal6
    from emp
    where deptno =30;

    6.listagg分类汇总

    with l as
    (select level as lv from dual connect by level<=9),
    m as 
    (select a.lv as alv,b.lv as blv,
               to_char(b.lv)|| 'x'|| to_char(a.lv)||' = '|| rpad(to_char(a.lv*b.lv),2,' ') as text
      from l a,l b
      where b.lv<=a.lv)
    select listagg(m.text,'  ') within GROUP(order by m.blv) as 小九九
    from m
    group by m.alv;
  • 相关阅读:
    java基础学习总结——面向对象1
    java基础学习总结——基础语法2
    java基础学习总结——基础语法1
    java基础学习总结——开篇
    java基础学习总结——java环境变量配置
    Java基础加强总结(二)——泛型
    Java基础加强总结(一)——注解(Annotation)
    Web开发中设置快捷键来增强用户体验
    SQLServer2005中的CTE递归查询得到一棵树
    Jquery操作table
  • 原文地址:https://www.cnblogs.com/zhulongchao/p/4545121.html
Copyright © 2011-2022 走看看