上 面的语句很容易实现对应区域每个月的销售额的汇总统计,但是更复杂的需求,我们可能要对跨越所有月份的每个区域单独汇总,生成小计,并且加上所有区域的汇 总或者对应每个月跨越所有区域,生成小计,并且加上所有月的汇总统计,简而言之,也就是要实现多级别小计和总计的统计。实现这个需求,简单的 group by就无法实现了,下面逐步研究实现的方法。
从上面结果可以看出,红色部分为group by null,null的结果,计算合计值。黄色部分为group by null,month的结果,计算每个月中所有区域的小计。绿色为group by name,null的结果,计算每个区域所有月份的小计。灰色的为group by name,month的结果。其中:
group by name,month的所有结果的和=group by name,null的和=group by null,month的和=合计值。
group by name,month中对应name的和=group by name,null对应的name的值。
group by name,month中对应month的和=group by null,month对应month的和。
当然对于cube的运算,和rollup一样,也可以使用union实现,但是cube的组合方式呈级数增长,则union也会增长,而且性能不好,访问表多次,无cube的优化,语句没有cube简单。上例我们可以使用对应的4个group by 然后union all获得结果,但是结果的顺序不能保证。
由上面的结果分析,GROUP BY ROLLUP ((o.year, o.month),r.name)相当于group by (o.year,o.month),r.name、group by (o.year,o.month),null和group by null,null三个的union结果。与GROUP BY ROLLUP (o.year, o.month,r.name)少了group by rollup o.year,null,null。按年计算所有月份的小计。因为(o.year,o.month)是复合列,相当于一个列,不可分隔。
group by 中使用复合列的好处在于过滤某些本来有的结果。比如上例就过滤了按年计算所有月份的小计值,但是保留了最后的合计值。如果使用前面说的局部 rollup:group by o.year,rollup(o.month,r.name)则会丢掉最后的合计值,而且包含了按年统计所有月份的小计 值,总之,应该根据具体需求,选择合适的方案。
:?等价于?GROUP BY ROLLUP (o.year, o.month), ROLLUP(r.name)
GROUP BY o.year,o.month,r.name
GROUP BY o.year,null,r.name
GROUP BY null,null,r.name
GROUP BY null,null,null
GROUP BY o.year,o.month,null
GROUP BY o.year,null,null
的union all的结果。提供了比rollup(o.year,o.month,r.name)更多的分组功能,多了一个GROUP BY o.year,null,r.name。
group by null。因此才出现上述的6种分组结果:分组的结果为3*2=6,而没有group by null,o.month,r.name和group by null,o.month,null这两种结果。?group by null,null。第2个rollup(r.name)的执行顺序是group by r.name?group by o.year,null? 当 在group by中使用多个rollup,cube,grouping sets操作的时候,我们叫这样的分组为级联分组。级联分组的结果就是产生每个 单独分组操作的交叉列表,但是要符合每个操作的处理步骤,比如上面的 GROUP BY ROLLUP (o.year, o.month), ROLLUP(r.name)操作,第1个rollup(o.year,o.month)的执行顺序是group by o.year,o.month
根据上述的规则,我们将rollup(o.year,o.month)改为cube(o.year,o.month),那么cube的计算种类是4中,后面的rollup(r.name)为两种,那么这种级联分组应该有相当于group by的分类为4*2=8种,比rollup(o.year,o.month),rollup(r.name)多了group by null,o.month,r.name和group by null,o.month,null这两种结果。我们看下结果: