1.行转列:有两种写法,一种是case when end写法,另一种写法是pivot(oracle 11g新增)
- select job,
- sum(case deptno when then sal end) as sal10,
- sum(case deptno when then sal end) as sal20,
- sum(case deptno when then sal end) as sal30,
- sum(sal) as allsal
- from emp
- group by job
- order by ;
- select *
- from (select job,sal,deptno from emp)
- pivot(sum(sal) as s for deptno in( as d10,, as d30))
- order by ;
pivot的维护比case when end简洁,当增加一个统计属性时,只需增加一个sum函数。
pivot一次只能实现一个属性的行专列,多个属性的行转列只能采用case when end
执行计划:pivot在执行时,还是被翻译成了case when end.
2.列转行:有两种写法,一种是union all,另一种是unpivot分析函数
- select ‘’ as deptno, deptno_10_ct as rc from test
- union all
- select '' 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 ,deptno_20_ct as ))
- unpivot include null(sal for deptno1 in(deptno_10_s as ,deptno_20_s as ))
- 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=
- order by job,ename
注意order by优先使用select 中别名.
3.ntile函数,对数据按照指定数量进行分组优化
- select ntile() 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 then '总计' else to_char(deptno) end as code,
- case when grouping(deptno)= then null when grouping(job)= then '小计' else job end as gz,
- case when grouping(job)= then null when grouping(mgr)= then '小小计' else to_char(mgr) end as mmgr,
- max(case when empno in(,,) 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 '' then 'gdepjob'
- when '' then 'gdep'
- when '' then 'gjob'
- when '' 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 =;
6.listagg分类汇总
- with l as
- (select level as lv from dual connect by level<=),
- 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),,' ') 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;
以上就是Oracle Sql优化之报表和数据仓库运算的详细内容,更多关于Oracle Sql优化之报表和数据仓库运算的资料请关注九品源码其它相关文章!