Hive_Hive ROLLUP, GROUPING SETS, CUBE 聚合函数 GROUPING 函数 与 GROUPING__ID 计算方式

    在  ROLLUP,   GROUPING SETS , CUBE 函数中 , 我们会需要用到 GROUPING 函数  与  GROUPING__ID 。

这几个函数的使用方法,请参考我的文章 :

https://blog.csdn.net/u010003835/article/details/105353510

GROUPING 函数

 

下面,我们先讲解下 GROUPING 函数

  GROUPING 函数   可以与CUBE , ROLLUP,  GROUPING SETS 一起使用, 它能帮助你理解概要值是怎样产生的。

但是貌似我的HIVE 版本有问题,做不了实验

直接贴官方文档链接了

https://cwiki.apache.org/confluence/display/Hive/Enhanced+Aggregation%2C+Cube%2C+Grouping+and+Rollup#EnhancedAggregation,Cube,GroupingandRollup-Groupingfunction

上原文,原始数据

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:

SELECT key, value, GROUPING__ID,

  grouping(key, value), grouping(value, key), grouping(key), grouping(value),

  count(*)

FROM T1

GROUP BY key, value WITH ROLLUP;

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

发布了519 篇原创文章 · 获赞 1146 · 访问量 283万+

猜你喜欢

转载自blog.csdn.net/u010003835/article/details/105373889