在 ROLLUP, GROUPING SETS , CUBE 函数中 , 我们会需要用到 GROUPING 函数 与 GROUPING__ID 。
这几个函数的使用方法,请参考我的文章 :
https://blog.csdn.net/u010003835/article/details/105353510
GROUPING 函数
下面,我们先讲解下 GROUPING 函数
GROUPING 函数 可以与CUBE , ROLLUP, GROUPING SETS 一起使用, 它能帮助你理解概要值是怎样产生的。
但是貌似我的HIVE 版本有问题,做不了实验
直接贴官方文档链接了
上原文,原始数据
Column1 (key) |
Column2 (value) |
---|---|
1 |
NULL |
1 |
1 |
2 |
2 |
3 |
3 |
3 |
NULL |
4 |
5 |
Grouping function
The grouping function indicates whether an expression in a GROUP BY clause is aggregated or not for a given row. The value 0 represents a column that is part of the grouping set, while the value 1 represents a column that is not part of the grouping set.
Going back to our example above, consider the following query:
|
This query will produce the following results.
Column 1 (key) |
Column 2 (value) |
GROUPING__ID |
grouping(key, value) |
grouping(value, key) |
grouping(key) |
grouping(value) |
count(*) |
---|---|---|---|---|---|---|---|
NULL |
NULL |
3 |
3 | 3 | 1 |
1 | 6 |
1 |
NULL |
0 |
0 | 0 | 0 |
0 | 2 |
1 |
NULL |
1 |
1 | 2 | 0 |
1 | 1 |
1 |
1 |
0 |
0 | 0 | 0 |
0 | 1 |
2 |
NULL |
1 |
1 | 2 | 0 |
1 | 1 |
2 |
2 |
0 |
0 | 0 | 0 |
0 | 1 |
3 |
NULL |
0 |
0 | 0 | 0 |
0 | 2 |
3 |
NULL |
1 |
1 | 2 | 0 |
1 | 1 |
3 |
3 |
0 |
0 | 0 | 0 |
0 | 1 |
4 |
NULL |
1 |
1 | 2 | 0 |
1 | 1 |
4 |
5 |
0 |
0 | 0 | 0 |
0 | 1 |
GROUPING__ID 计算方式
下面我们讲解下 GROUPING__ID 的计算方式
数据统计背景:
我们现在有多个公司,多个部门,多位员工的薪水情况。现在我们需要按照多种维度去统计薪水。
构建下基础的表
use data_warehouse_test;
CREATE TABLE IF NOT EXISTS datacube_salary_org (
company_name STRING COMMENT '公司名称'
,dep_name STRING COMMENT '部门名称'
,user_id BIGINT COMMENT '用户id'
,user_name STRING COMMENT '用户姓名'
,salary DECIMAL(10,2) COMMENT '薪水'
,create_time DATE COMMENT '创建时间'
,update_time DATE COMMENT '修改时间'
)
PARTITIONED BY(
pt STRING COMMENT '数据分区'
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
;
导入数据
创建一个txt 文件,填入以下内容:
s.zh,engineer,1,szh,28000.0,2020-04-07,2020-04-07
s.zh,engineer,2,zyq,26000.0,2020-04-03,2020-04-03
s.zh,tester,3,gkm,20000.0,2020-04-07,2020-04-07
x.qx,finance,4,pip,13400.0,2020-04-07,2020-04-07
x.qx,finance,5,kip,24500.0,2020-04-07,2020-04-07
x.qx,finance,6,zxxc,13000.0,2020-04-07,2020-04-07
x.qx,kiccp,7,xsz,8600.0,2020-04-07,2020-04-07
创建分区,LOAD文件
LOAD 文件
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)]
创建分区
ALTER TABLE datacube_salary_org ADD PARTITION (pt = '20200405');
导入数据
LOAD DATA LOCAL INPATH '/opt/hive/my_script/data_warehouse_test/rollup_table/org_data.txt' OVERWRITE INTO TABLE datacube_salary_org PARTITION (pt = '20200405');
下面我们利用 ROLLUP, 看下GROUPING_ID 的计算规则
SELECT
grouping__id
,company_name
,dep_name
,user_id
,SUM(salary) AS total_salary
FROM datacube_salary_org
WHERE pt = '20200407'
GROUP BY
company_name
,dep_name
,user_id
WITH ROLLUP
ORDER BY
grouping__id
;
可以看到 GROUP BY 中有 三个字段, 依次是 company_name, dep_name, user_id
可以看作3位二进制
即 (0/1),(0/1),(0/1)
低位对应 company_name
高位对应 user_id
如果这一位聚合了(GROUP BY 中存在该字段),则为0,GROUPING 函数对应也返回0
最后 GROUPING_ID 为对应2进制 转换的 10进制数。
1) ROLLUP 按所有字段分组的子集
相当于如下SQL语句
SELECT
company_name
,dep_name
,user_id
,SUM(salary) AS total_salary
FROM datacube_salary_org
WHERE pt = '20200407'
GROUP BY
company_name
,dep_name
,user_id
对应的结果
+---------------+---------------+-----------+----------+---------------+
| grouping__id | company_name | dep_name | user_id | total_salary |
+---------------+---------------+-----------+----------+---------------+
| 7 | x.qx | kiccp | 7 | 8600.00 |
| 7 | x.qx | finance | 6 | 13000.00 |
| 7 | x.qx | finance | 5 | 24500.00 |
| 7 | x.qx | finance | 4 | 13400.00 |
| 7 | s.zh | enginer | 2 | 26000.00 |
| 7 | s.zh | enginer | 1 | 28000.00 |
| 7 | s.zh | tester | 3 | 20000.00 |
+---------------+---------------+-----------+----------+---------------+
因为 GROUP BY 这三个字段都有,二进制表示法为 111 ,所以 GROUPING__ID 为7。
2) ROLLUP 按company_name, dep_name 分组的子集
相当于SQL
SELECT
company_name
,dep_name
,NULL
,SUM(salary) AS total_salary
FROM datacube_salary_org
WHERE pt = '20200407'
GROUP BY
company_name
,dep_name
对应的结果
+---------------+---------------+-----------+----------+---------------+
| grouping__id | company_name | dep_name | user_id | total_salary |
+---------------+---------------+-----------+----------+---------------+
| 3 | s.zh | tester | NULL | 20000.00 |
| 3 | x.qx | kiccp | NULL | 8600.00 |
| 3 | x.qx | finance | NULL | 50900.00 |
| 3 | s.zh | enginer | NULL | 54000.00 |
+---------------+---------------+-----------+----------+---------------+
结合上面的规则
可以看到 GROUP BY 中有 三个字段, 依次是 company_name, dep_name, user_id
可以看作3位二进制
即 (0/1),(0/1),(0/1)
低位对应 company_name
高位对应 user_id
因为上面的字段是 GROUP BY company_name ,dep_name
则 GROUPING__ID 为 011 ,即为 3