10.1.6 GROUPING SETS
以上我们已经掌握了rollup,cube分组统计的知识。但是rollup和cube的分组统计包含了常规group by的统计明细以及对相关列的小计和合计值。如果我们需要的只是按每个分组列小计呢?oracle提供了grouping sets操作,对group by的另一个扩展,专门对分组列分别进行小计计算,不包括合计。使用方式和rollup和cube一样,都是放在group by中。如:
grouping sets(C1,C2….Cn)则分组方式有n种,等于列的数目。
group by c1,null,null…..null。
group by null,c2,null….null。
….
group by null,null……..Cn。
无group by null,null….null,也就是说没有合计行。
注意:grouping sets的统计结果和列的顺序无关。
如下例:
SELECT o.year, TO_CHAR(TO_DATE(o.month, 'MM'), 'Month') month,
r.name region, SUM(o.tot_sales) sums
FROM all_orders o JOIN region r
ON r.region_id = o.region_id
WHERE o.month BETWEEN 1 AND 3
GROUP BY GROUPING SETS (o.year, o.month, r.name);
YEAR MONTH REGION SUMS
----- -------------------- -------------------- ------------------------------------------------
New England 5074332
Mid-Atlantic 5029212
Southeast US 4960311
January 4496799
February 4988535
March 5578521
2001 5021285
2000 10042570
可以看出,没有常规group by统计结果,只有按每个单独列的小计,也不包含合计。改变grouping sets中列的顺序,不影响结果,上面的语句等价于:
SELECT o.year, TO_CHAR(TO_DATE(o.month, 'MM'), 'Month') month,
r.name region, SUM(o.tot_sales) sums
FROM all_orders o JOIN region r
ON r.region_id = o.region_id
WHERE o.month BETWEEN 1 AND 3
GROUP BY GROUPING SETS (o.month, r.name, o.year);
10.1.7ROLLUP、CUBE、GROUPING SETS总结
本章已经学习了小计和合计的三个主要增强的group by操作:rollup,cube,grouping sets操作。下面总结下他们的使用以及区别。
操作名 简述 列顺序是否要求 分组情况 使用情况
ROLLUP ROLLUP操作可以查询出常规group by的结果以及按列小计和合计的结果。 和列顺序有关。见分组情况。 ROLLUP(C1,C2…Cn)。
总共会进行n+1个分组。那么实际上有n+1个group by的union all结果。
顺序为:
group by C1,C2….Cn
group by C1,C2,….Cn-1
group by C1,C2….Cn-2
----
group by C1
group by null,….null
可以看出是从右到左逐渐递减列的group by,所以和列的顺序有关,顺序不同,意义不同。
需要查询的分组明细以及小计和合计功能的时候使用。
CUBE CUBE操作是对所有可能的列组合分组,包括常规group by以及所有分组小计和合计的值。 和列顺序无关。 CUBE(C1,C2,C3……C(N))对N个列进行CUBE分组,那么可能的分组情况有:
不分组:C(n,0)
取一列分组:C(n,1)
-----
取N列分组,全分组:C(n,n)
那么运用数学上的组合公式,得出所有所有可能的组合方式有:C(n,0)+C(n,1)+….+C(n,n)=2^n种。
如果只有一个列,那么和rollup一样。
比如cube(name,month)
分组情况有:
group by null,null //总计C(2,0)
group by null,month //每个月份的所有区域小计
group by name,null //每个区域的所有月份小计 C(2,1)
group by name,month //C(2,2)常规group by
因此,结果和列的顺序无关。
适用于需要统计各种可能的组合情况的小计和合计以及常规分组明细。
GROUPING SETS 只查询按每个列小计的结果,不包含合计值 和列顺序无关。 分组种类=列的数目。
grouping sets(C1,C2,…Cn)
那么等价于下列union all
group by C1,null…..
group by null,C2….
…
group by null,null….Cn 适用于只需要按每个列小计。