Oracle的rollup、cube、grouping sets函数


Oraclegroup by除了基本用法以外,还有3种扩展用法,分别是rollupcubegrouping sets

1 rollup

假设有一个表test,有ABCDE5列。

如果使用group by rollup(A,B,C),首先会对(ABC)进行GROUP BY,然后对(AB)进行GROUP BY,然后是(A)进行GROUP BY,最后对全表进行GROUP BY操作。roll up的意思是“卷起”,这也可以帮助我们理解group by rollup就是对选择的列从右到左以一次少一列的方式进行grouping直到所有列都去掉后的grouping(也就是全表grouping),对于n个参数的rollup,有n+1次的grouping。以下2sql的结果集是一样的:

Select A,B,C,sum(E) from test group by rollup(A,B,C)

Select A,B,C,sum(E) from test group by A,B,C

union all

Select A,B,null,sum(E) from test group by A,B

union all

Select A,null,null,sum(E) from test group by A

union all

Select null,null,null,sum(E) from test

2 cube

cube的意思是立方,对cube的每个参数,都可以理解为取值为参与grouping和不参与grouping两个值的一个维度,然后所有维度取值组合的集合就是grouping的集合,对于n个参数的cube,有2^n次的grouping。如果使用group by cube(A,B,C),,则首先会对(ABC)进行GROUP BY,然后依次是(AB)(AC)(A)(BC)(B)(C),最后对全表进行GROUP BY操作,一共是2^3=8grouping。同rollup一样,也可以用基本的group by加上结果集的union all写出一个与group by cube结果集相同的sql

Select A,B,C,sum(E) from test group by cube(A,B,C);

Select A,B,C,sum(E) from test group by A,B,C

union all

Select A,B,null,sum(E) from test group by A,B

union all

Select A,null,C,sum(E) from test group by A,C

union all

Select A,null,null,sum(E) from test group by A

union all

Select null,B,C,sum(E) from test group by B,C

union all

Select null,B,null,sum(E) from test group by B

union all

Select null,null,C,sum(E) from test group by C

union all

Select null,null,null,sum(E) from test;

3 grouping sets

grouping sets就是对参数中的每个参数做grouping,也就是有几个参数做几次grouping,例如使用group by grouping sets(A,B,C),则对(A),(B),(C)进行group by,如果使用group by grouping sets((A,B),C),则对(A,B),(C)进行group by。甚至grouping by grouping set(A,A)都是语法允许的,也就是对(A)进行2group by,grouping sets的参数允许重复

4 总结

rollup        (N+1个分组方案)

cube         (2^N个分组方案)

grouping sets (自定义罗列出分组方案)

5 注意点

5.1 机制不同

rollupcube的说明中分别给出了用基本group by加结果集union all给出了结果集相同的sql,但这只是为了理解的方便而给出的sql,并不说明rollupcube与基本group by加结果集union all等价。实际上两者的内部机制是安全不一样的,前者除了写法简洁以外,运行时不需多次扫描表,效率远比后者高。

5.2 集合可运算

3种扩展用法的参数可以是源表中的某一个具体的列,也可以是若干列经过计算而形成的一个新列(比如说A+BA||B),也可以是这两种列的一个集合(例如(A+BC)),对于grouping set更是特殊,可以是空集合(),表示对全表进行group by

5.3 group by rollup, cube组合使用

3Group by的基本用法以及这3种扩展用法可以组合使用,也就是说可以出现group by A,rollup(A,B)这样的用法,oracle将对出现在group by中的每种用法的grouping列集合做笛卡尔积然后对其中的每一个元素做group by。这话说起来挺绕口,举例说明吧,group by A, rollup(A,B),基本用法的grouping集合是(A),rollup(A,B)grouping集合是((A,B),(A),()),两个集合的笛卡尔积集合是((A,A,B),(A,A),(A)),所以会首先对(A,A,B)group by,然后对(A,A)group by,最后对(A)group by。实际上对(A,A,B)group by和对(A,B)group by两者是完全等价的(group by A,A,B结果和group by A,B完全一样),同理对(A,A)group by和对(A)group by也是等价的。简化后的结果就是首先对(A,B)group by,然后对(A)group by,最后再对(A)group by。下面给出两个等价的sql以便理解:

Select A,B,sum(E) from test1 group by A, rollup(A,B);

Select A,B,sum(E) from test1 group by A,B

Union all

Select A,null,sum(E) from test1 group by A

Union all

Select A,null,sum(E) from test1 group by A;

  • 1
  • 2
  • 下一页

相关内容