create table test_group_table(
t_year number,
t_month number,
quantity number
);
然后插入相应的测试数据:
insert into test_group_table values(2012,1,29);
insert into test_group_table values(2012,1,39);
insert into test_group_table values(2012,2,11);
insert into test_group_table values(2012,3,12);
insert into test_group_table values(2013,1,10);
insert into test_group_table values(2013,2,20);
insert into test_group_table values(2013,3,30);
insert into test_group_table values(2013,4,40);
正常状态下,我们使用普通的group by 子句: select t_year,t_month, sum(quantity) qty from test_group_table group by t_year,t_month;得到的返回结果如下:
2012 3 12
2012 1 68
2013 2 20
2012 2 11
2013 1 10
2013 3 30
2013 4 40
上面的结果不不包含合计及小计的内容;这时如果我们使用分组函数rollup,该函数将会在结果集中增加小计及合计的内容,执行select t_year,t_month, sum(quantity) qty from test_group_table group byrollup(t_year,t_month),得到的结果如下:
2012 1 30
2012 2 43.5
2012 3 55.5
2012 4 20
2012 149
2013 1 808
2013 808
957
上面结果集中红色部分即是/根据年份(t_year)的小计及最后的所有数量的合计值.
如果我们使用cube分组函数时,执行分组sql(select t_year,t_month, sum(quantity) qty from test_group_table group bycube(t_year,t_month);)得到的结果如下:
957
1 838
2 43.5
3 55.5
4 20
2012 149
2012 1 30
2012 2 43.5
2012 3 55.5
2012 4 20
2013 808
2013 1 808
上面的结果中红色部分即为cube结果比rollup多出来的针对月份(t_month)的合计数量值。
而使用grouping sets扩展分组函数时,即执行sql(select t_year,t_month, sum(quantity) qty from test_group_table group bygroupint sets(t_year,t_month)),将返回的结果集为为:
1 838
2 43.5
3 55.5
4 20
2013 808
2012 149
该结果集比cube的结果集只有针对年份和针对月份的分组值,并且没有合部记录的合计值;
下面我们再说一下having及select 后面可以使用的grouping(单列)函数,grouping_id(多列),及group_id()的使用方法:
select t_year,t_month, sum(quantity) qty,grouping(t_year),grouping(t_month) from test_group_table group byrollup(t_year,t_month);返回的结果集为:
2012 1 30 0 0
2012 2 43.5 0 0
2012 3 55.5 0 0
2012 4 20 0 0
2012 149 0 1
2013 1 808 0 0
2013 5 907.54 0 0
2013 1715.54 0 1
1864.54 1 1通过上面的结果集我们可以看到最后一列是全部结果的合计值,因此年份和月份列均为空因此均返回了1,而第5行和第8行的小计行,因为年份不为空,但月份为空,因此grouping(t_year)返回了0,而grouping(t_month)返回了1,注意,如果t_year列本身值即为空,则grouping(t_year)仍然返回0;
如果我们只想返回合部合计的结果集,则可以在having子句中增加相应的判断,执行sql(select t_year,t_month, sum(quantity) qty,grouping(t_year),grouping(t_month) from test_group_table group byrollup(t_year,t_month) having grouping(t_year) = 1 and grouping(t_month) = 1)将只返回:
1864.54 1 1
而如果执行select t_year,t_month, sum(quantity) qty,grouping(t_year),grouping(t_month) from test_group_table group by rollup(t_year,t_month) havinggrouping(t_year) = 0 and grouping(t_month) = 1
则返回 的结果集为:
2012 149 0 1
2013 1715.54 0 1因此我们可以使用grouping(单列)来进行相关数据的过滤操作.
grouping_id(多列)的使用方法基本与grouping(单列)类似,但grouping_id可以传入多列,如果转入一列的情况下,它的返回结果也是列值为空则返回1,否则返回0;但如果参数转入为多列,则其的计算方式如下,我们以grouping(t_year,t_month)为例说明:
如果t_year,t_month列均为空则grouping_id(t_year,t_month)返回值为二进制的11,转为10进制为3;
t_year为空,t_month不为空则返回值为10,转为10进制为2;
t_year不为空,t_month为空,则返回值为01转为10进制为1;