wer(2,n) 种。
将 2.2 节使用 ROLLUP(dname,job) 替换为 CUBE select d.dname,e.job,sum(e.sal) from dept d,emp e where d.deptno=e.deptno group by cube(d.dname,e.job); 下图分析 CUBE(dname,job) 对应分组级别:
3.2 部分 CUBE 分组 和 ROLLUP 一样,也有部分 CUBE 操作,可以去掉合计及某些不需要的小计,比如上面的 GROUP BY CUBE(d.dname,e.job) 改为 GROUP BY d.dname CUBE(e.job) 则剔除了合计及GROUP BY job。 select d.dname,e.job,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by d.dname,cube(e.job); <=> select d.dname,e.job,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by d.dname,e.job union all select null,null,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by d.dname;
3.3 CUBE总结 先进行合计,然后小计,最后再按标准分组
4. GROUPING SETS 实现小计 前面所说的两种多维数据统计的方法,即 ROLLUP 和 CUBE,它们的输出结果是由对应分组的行伴随 着小计行产生的,它们会产生标准分组、各种小计及总计,但是有时候我们只关心某个单列分组,从而 得到其它维度小计的信息,这样就需要使用 GROUPING SETS扩展分组,它是Oracle9i提供的。 比如 GROUP BY GROUPING SETS(a,b,c) 相当于 GROUP BY a、GROUP BY b、GROUP BY c 这三 个单列分组,从而得到其他维度的小计信息。 n列的 GROUPING SETS 的分组总类有 n 个。 4.1 GROUPING SETS 分组 语法结构: SELECT ... GROUP BY GROUPING SETS(grouping_column_reference_list) 将2.2节中的 ROLLUP 改为 GROUPING SETS select to_char(e.hiredate,'yyyy') hireyear,d.dname,e.job,sum(e.sal) sum_sal from emp e,dept d where e.deptno=d.deptno group by grouping sets(to_char(e.hiredate,'yyyy'),d.dname,e.job); 注:GROUPING SETS 的结果是分别按单列分组后 UNION ALL的结果; GROUPING SETS 的结果和列的顺序没有关系,而且结果的顺序也是无序的。
4.2 部分 GROUPING SETS 分组 select d.dname,to_char(e.hiredate,'yyyy') hireyear,e.job,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by d.dname,grouping sets(to_char(e.hiredate,'yyyy'),e.job); <=> select d.dname,to_char(e.hiredate,'yyyy') hiredate,null job,sum(e.sal) sum_sal from dept d,emp e
where d.deptno=e.deptno group by d.dname,to_char(e.hiredate,'yyyy') union all select d.dname,null,e.job,sum(e.sal) sum_sal from dept d,emp e
where d.deptno=e.deptno group by d.dname,e.job;
上述语句统计的是:对于每个部门每个入职时间(年),对所有职位进行小计及 对于每个部门每个职位,对每个入职时间(年)进行小计。
4.3 CUBE、GROUPING 作为 GROUPING SETS 的参数 GROUPING SETS 操作能够接受 ROLLUP 和 CUBE 作为它的参数,GROUPING SETS 操作只对 单列进行分组,而不提供合计的功能,如果需要 GROUPING SETS 提供合计的功能,那么可以使 用 ROLLUP 或 CUBE 作为 GROUPING SETS 的参数。 改写前面的 GROUPING SETS(d.dname,e.job),提供合计功能。 select d.dname,e.job,sum(e.sal) from dept d,emp e where d.deptno=e.deptno group by grouping sets(rollup(d.dname),rollup(e.job)); <=> select d.dname,null job,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by rollup(d.dname) union all select null dname,e.job,sum(e.sal) sum_sal from dept d,emp e where d.deptno=e.deptno group by rollup(e.job); 注:上述语句会产生两个合计行,因为 ROLLUP 或 CUBE 作为 GROUPING SETES 的参数,相当 于对每个 ROLLUP 或 CUBE 操作的 UNION ALL; 可使用 DISTINCT 剔除重复行; ROLLUP 和 CUBE 不能接受 GROUPING SETS 作为参数,ROLLUP 和 CUBE 之间相互作为 参数也不可以。
4.4 GROUPING SETS 总结 GROUPING SETS 的结果和列的顺序没有关系,而且结果的顺序也是无序的。
5. 组合列分组、连接分组、重复列分组 组合列分组、连接分组、重复列分组都是Oracle 9i 中才有的特性。组合列也就是将多个列用括号括 起来,从而将多个列当做整体对待,比如 GROUP BY ROLLUP((a,b),c) 相当于 GROUP BY ROLLUP(x,c) ,其中 x 相当于 (a,b) 这个组合列。组合列一般在 in 条件中比较常见,比如: -- where in 中使用组合列 select empno,ename,job from emp where (empno,ename) in ((7369,'SMITH'),(7499,'ALLEN')); 下图是普通列 ROLLUP 和组合列 ROLLUP 的对比(CUBE、GROUPING SETS类似)
上图的组合列分组达到了剔除某些小计的功能,且保证了最终结果又合计行。
连接分组允许在 GROUP BY 之后出现多个 ROLLUP、CUBE、GROUPING SETS 操作,这样分组级别 更多,报表更加精细。
实际上不管是同类型的连接分组还是不同类型的连接分组之间,最后的分组级别种类都是每个扩展 分组级别种类的乘积,分组级别是笛卡尔积。比如同类型连接分组 ROLLUP(a,b),ROLLUP(c) 最终 结果有 3*2=6 种分组级别,不同类型连接分组 ROLLUP(a,b),G |