ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解析数仓OLAP函数:ROLLUP、CUBE、GROUPING SETS

2022-04-27 12:04:05  阅读:224  来源: 互联网

标签:customer 数仓 CUBE 200 country sum ROLLUP 100 class


摘要:GaussDB(DWS) ROLLUP,CUBE,GROUPING SETS等OLAP函数的原理解析。

本文分享自华为云社区《GaussDB(DWS) OLAP函数浅析》,作者: DWS_Jack_2。

在一些报表场景中,经常会对数据做分组统计(group by),例如对一级部门下辖的二级部门员工数进行统计:

create table emp(
id int,     --工号
name text,  --员工名
dep_1 text, --一级部门
dep_2 text  --二级部门
);
gaussdb=# select count(*), dep_2 from emp group by dep_2;
 count | dep_2
-------+-------
   200 | SRE
   100 | EI
(2 rows)

常见的统计报表业务中,通常需要进一步计算一级部门的“合计”人数,也就是二级部门各分组的累加,就可以借助于rollup,如下所示,比前面的分组计算结果多了一行合计的数据:

gaussdb=# select count(*), dep_2 from emp group by rollup(dep_2);
 count | dep_2
-------+-------
   200 | SRE
   100 | EI
   300 |
(3 rows)

如上是一种group by扩展的高级分组函数使用场景,这一类分组函数统称为OLAP函数,在GaussDB(DWS)中支持 ROLLUP,CUBE,GROUPING SETS,下面对这几种OLAP函数的原理和应用场景做一下分析。

首先我们来创建一张表,customer,用户信息表,其中包含了用户id,用户名,年龄,国家,用户级别,性别,余额等信息:

create table customer
(
 c_id char(16) not null,
 c_name char(20) ,
 c_age integer ,
 c_country varchar(20) ,
 c_class char(10),
 c_sex text,
 c_balance numeric
);
insert into customer values(1, 'tom', '20', 'China', '1', 'male', 300);
insert into customer values(2, 'jack', '30', 'USA', '1', 'male', 100);
insert into customer values(3, 'rose', '40', 'UK', '1', 'female', 200);
insert into customer values(4, 'Frank', '60', 'GER', '1', 'male', 100);
insert into customer values(5, 'Leon', '20', 'China', '2', 'male', 200);
insert into customer values(6, 'Lucy', '20', 'China', '1', 'female', 500);

ROLLUP

本文开头的示例已经解释了,ROLLUP是在分组计算基础上增加了合计,从字面意思理解,就是从最小聚合级开始,聚合单位逐渐扩大,例如如下语句:

select c_country, c_class, sum(c_balance) from customer group by rollup(c_country, c_class) order by 1,2,3;
 c_country |  c_class   | sum  
-----------+------------+------
 China     | 1          |  800
 China     | 2          |  200
 China     |            | 1000
 GER       | 1          |  100
 GER       |            |  100
 UK        | 1          |  200
 UK        |            |  200
 USA       | 1          |  100
 USA       |            |  100
           |            | 1400
(10 rows)

该语句功能等价于如下:

select c_country, c_class, sum(c_balance) from customer group by c_country, c_class
union all
select c_country, null, sum(c_balance) from customer group by c_country
union all
select null, null, sum(c_balance) from customer order by 1,2,3;
 c_country |  c_class   | sum  
-----------+------------+------
 China     | 1          |  800
 China     | 2          |  200
 China     |            | 1000
 GER       | 1          |  100
 GER       |            |  100
 UK        | 1          |  200
 UK        |            |  200
 USA       | 1          |  100
 USA       |            |  100
           |            | 1400
(10 rows)

尝试理解一下

GROUP BY ROLLUP(A,B):

首先对(A,B)进行GROUP BY,然后对(A)进行GROUP BY,最后对全表进行GROUP BY操作

CUBE

CUBE从字面意思理解,就是各个维度的意思,也就是说全部组合,即聚合键中所有字段的组合的分组统计结果,例如如下语句:

select c_country, c_class, sum(c_balance) from customer group by cube(c_country, c_class) order by 1,2,3;
 c_country |  c_class   | sum  
-----------+------------+------
 China     | 1          |  800
 China     | 2          |  200
 China     |            | 1000
 GER       | 1          |  100
 GER       |            |  100
 UK        | 1          |  200
 UK        |            |  200
 USA       | 1          |  100
 USA       |            |  100
           | 1          | 1200
           | 2          |  200
           |            | 1400
(12 rows)

该语句功能等价于如下:

select c_country, c_class, sum(c_balance) from customer group by c_country, c_class
union all
select c_country, null, sum(c_balance) from customer group by c_country
union all
select null, null, sum(c_balance) from customer
union all
select NULL, c_class, sum(c_balance) from customer group by c_class order by 1,2,3;
 c_country |  c_class   | sum  
-----------+------------+------
 China     | 1          |  800
 China     | 2          |  200
 China     |            | 1000
 GER       | 1          |  100
 GER       |            |  100
 UK        | 1          |  200
 UK        |            |  200
 USA       | 1          |  100
 USA       |            |  100
           | 1          | 1200
           | 2          |  200
           |            | 1400
(12 rows)

理解一下

GROUP BY CUBE(A,B):

首先对(A,B)进行GROUP BY,然后依次对(A)、(B)进行GROUP BY,最后对全表进行GROUP BY操作。

GROUPING SETS

GROUPING SETS区别于ROLLUP和CUBE,并没有总体的合计功能,相当于从ROLLUP和CUBE的结果中提取出部分记录,例如如下语句:

select c_country, c_class, sum(c_balance) from customer group by grouping sets(c_country, c_class) order by 1,2,3;
 c_country |  c_class   | sum  
-----------+------------+------
 China     |            | 1000
 GER       |            |  100
 UK        |            |  200
 USA       |            |  100
           | 1          | 1200
           | 2          |  200
(6 rows)

该语句功能等价于如下:

select c_country, null, sum(c_balance) from customer group by c_country
union all
select null, c_class, sum(c_balance) from customer group by c_class
order by 1,2,3;
 c_country |  ?column?  | sum  
-----------+------------+------
 China     |            | 1000
 GER       |            |  100
 UK        |            |  200
 USA       |            |  100
           | 1          | 1200
           | 2          |  200
(6 rows)

理解一下

GROUP BY GROUPING SETS(A,B):

分别对(B)、(A)进行GROUP BY计算

目前在GaussDB(DWS)中,OLAP函数的实现,会有排序(sort)操作,相比等价的union all操作,效率并不会有提升,后续会通过mixagg的支持来提升OLAP函数的执行效率,有兴趣的同学,可以explain打印一下计划,来看一下OLAP函数的执行流程。

 

点击关注,第一时间了解华为云新鲜技术~

标签:customer,数仓,CUBE,200,country,sum,ROLLUP,100,class
来源: https://www.cnblogs.com/huaweiyun/p/16198345.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有