Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
0 Kudos

   SELECT查询语句中,可以使用GROUP BY子句来实现按照某一列或者几列进行分组,并可以再结合聚合函数对每个分组进行统计计算。同样,也可以使用同一个关键字,在同一语句中实现同时对不同分组进行统计,其结果即相当于将多个GROUP BY语句的结果进行UNION ALL后的结果。在下文中,将介绍使用GROUPING SETS, ROLLUPCUBE实现完成这个目的。


语法:

SELECT <attributes> [, grouping_id(<attributes>) ]   [, text_filter(dimensional_attribute) ]

FROM …

GROUP BY GROUPING SETS [BEST n] [LIMIT n] [OFFSET n]

[WITH SUBTOTAL] [WITH BALANCE] [WITH TOTAL]

[TEXT_FILTER <filterspec> [FILL UP [SORT MATCHES TO TOP]]]

[STRUCTURED RESULT [WITH OVERVIEW] [PREFIX ‘value’]]

( <group>, …, <group> )

HAVING <having-filter>;

<group> := <attribute> |( <attribute>, …, <attribute> ) |(( <attribute>, …, <attribute> ) ORDER BY <attribute> [ASC] [DESC])

GROUPING SETS

可以使用GROUPING SETS来指定使用那些列的组合进行分组。

例如:GROUPING SETS(A, B, (C,D))即指分别按照列A分组,按照列B分组,按照列CD分组,所得结果进行合并。

ROLLUPCUBEGROUPING SETS 的特殊形式。

ROLLUP

ROLLUP举例:

ROLLUP(A,B,C) 相当于GROUPING SETS((A,B,C),(A,B),A,()),即指分别按照列A,B,C分组,按照列A,B分组,按照列A分组,和不分组四种情况,所得结果进行合并。

即,ROLLUPgrouping set的个数为:n+1。

CUBE

CUBE举例:

CUBE(A,B,C)相当于GROPING SETS((A,B,C),(A,B),(A,C),(B,C),A,B,C,()),即指分别按照列A,B,C分组,按照列A,B分组,按照列A,C分组,按照列B,C分组,按照列A分组,按照列B分组,按照列C分组,和不分组八种情况,所得结果进行合并。

即,CUBEgrouping set的个数为:1+C(n,1)+C(n,2)+…+C(n,n-1)+1=2n

举例:

设计一个SALES 表,进行使用举例。


create columntable sales ( id int primarykey, customer varchar(5), year int, product varchar(5), sales int );
insert into sales values(1, 'C1', 2009, 'P1', 100);
insert into sales values(2, 'C1', 2009, 'P2', 200);
insert into sales values(3, 'C1', 2010, 'P1', 50);
insert into sales values(4, 'C1', 2010, 'P2', 150);
insert into sales values(5, 'C2', 2009, 'P1', 200);
insert into sales values(6, 'C2', 2009, 'P2', 300);
insert into sales values(7, 'C2', 2010, 'P1', 100);
insert into sales values(8, 'C2', 2010, 'P2', 150);
select * from sales;


GROUPING SETS


select customer, year, product, sum(sales) from sales
group by GROUPING SETS ( customer, year,product );


相当于:


select customer, NULL, NULL, sum(sales) from sales groupby customer
union all
select NULL, year, NULL, sum(sales) from sales group by year
union all
select NULL, NULL, product, sum(sales) from sales groupby product;


ROLLUP


select customer, year, sum(sales) from sales
group by ROLLUP(customer, year);


相当于:


select customer, year, sum(sales) from sales groupbygrouping sets ( (customer, year), (customer) )
union all
select NULL, NULL, sum(sales) from sales;


grouping_id()/grouping()

grouping_id()为每个grouping set返回一个整数,用来区分不同的grouping setgrouping()函数也返回一个整数,参数只能为某一列的列名,表示是否使用了这个列用来分组,只能返回01。


select customer, year, sum(sales),grouping_id(customer, year),grouping(customer),grouping(year) from sales
groupbyLU ROLP(customer, year);



select customer, year, sum(sales),grouping_id(customer, year),grouping(customer),grouping(year) from sales
groupby CUBE(customer, year);


注:以CUBE的例子来说明,grouping_id()中有CUSTMOERYEAR两列。则相当于存在一个两位的二进制数,最低位代表YEAR,另一位代表CUSTOMER,如果某个grouping set按照本列分组则代表它的位置1,否则置0。最后转换为十进制返回。


BEST

BEST nn可以为正数、负数或零,指取每个grouping set中分组的数降序排列后的前ngrouping set,即负数为除去不分组的情况按升序排列的前ngrouping set0则相当于未使用BEST 关键字。


select customer, year, product, sum(sales)
from sales groupby cube BEST 3 ( customer, year, product );

LIMIT OFFSET

LIMIT n [OFFSET m]:限制每个grouping set中返回的分组数和偏移数。


select customer, year, product, sum(sales)
from sales
groupbygrouping sets LIMIT 2 OFFSET 1 ( (customer, year), (product) );


WITH SUBTOTAL/WITH BALANCE/WITH TOTAL

可以和LIMIT OFFSET配合使用,表示在每个grouping set中新增一个统计列。WITH SUBTOTAL 表示在LIMIT OFFSET返回的部分使用统计函数,WITH BALANCE表示表示在LIMIT OFFSET未返回的部分使用统计函数,WITH TOTAL则表示使用统计函数的范围为整个grouping set,与是否使用LIMIT OFFSET 无关。


select customer, year, product, sum(sales)
from sales groupbygrouping sets LIMIT 2 WITH SUBTOTAL WITH BALANCE WITH TOTAL( (customer, year), (product) );


TEXT_FILTER

TEXT_FILTER <filterspec>,表示可以根据每列中存取的内容进行过滤。可以使用*?作为通配符,可以使用 OR ,AND, NOT, AND NOT这些逻辑操作符,空格相当于 OR,必须大写,-相当于NOT


select customer, year, product, sum(sales), text_filter(customer), text_filter(product)
from sales groupbygrouping sets TEXT_FILTER '*2' ( (customer, year), (product) );


FILL UP

FILL UPTEXT_FILTER结合使用,返回全部的分组,可以通过使用text_filter()函数来标识出满足过滤条件的内容。


select customer, year, product, sum(sales), text_filter(customer), text_filter(product)
from sales groupbygrouping sets TEXT_FILTER '*2' FILL UP ( (customer, year), (product) );


SORT MATCHES TO TOP

FILL UP 结合使用,将满足条件的排在每个grouping set的最前面。


select customer, year, product, sum(sales), text_filter(customer), text_filter(product)
from sales groupbygrouping sets TEXT_FILTER '*2' FILL UP SORT MATCHES TO TOP ( (customer, year), (product));


STRUCTURED RESULT [WITH OVERVIEW] [PREFIX ‘value’]

          STRUCTURED RESULT表示将结果作为临时表返回,WITH OVERVIEW则会新加一个overview的结果表。使用PREFIX指定临时表的前缀,必须以#开头,即local temporary表,session结束即消失。默认为#GN0 overviewn 是每个grouping sets的结果,按照grouping sets中顺序排序,否则按照best的顺序.


select customer, product, sum(sales)
from sales group by grouping sets structured result WITH OVERVIEW ( product, customer); 
select * from "#GN0";
select * from "#GN1";
select * from "#GN2";




MULTIPLE RESULTSETS

MULTIPLE RESULTSETS表示返回多个查询结果。


select customer, year, product, sum(sales)
from sales groupbygrouping sets MULTIPLE RESULTSETS ( (customer, year), (product) );

    想获取更多SAP HANA学习资料或有任何疑问,请关注新浪微博@HANAGeek!我们欢迎你的加入!转载本文章请注明作者和出处<http://scn.sap.com/community/chinese/hana/blog/2014/04/21/sap-hana%E4%B8%ADgrouping-sets-rollup-cube...>,请勿用于任何商业用途。