Hive之grouping sets用法及grouping_id计算方法

grouping sets 用法

在Hive中,会出现对同一个数据表进行不同粒度的汇总,这时可以有两种方案:

  1. 用多个sql,对不同粒度使用不同的 group by 方法。
  2. 用1个sql,使用 grouping sets 方法一次性得到所有粒度的汇总。

以测试数据表 tmp_student 为例:

1、生成测试数据

在 hive 环境中创建临时表:

create table tmp.tmp_student
(
   name string,
   class int,
   sex string,
   score int
)
row format delimited fields terminated by '|';

然后加载测试数据:

load data local inpath 'text.txt' into table tmp_student;

其中,text.txt 内容如下:

A|3|男|45
B|3|女|55
C|2|女|74
D|3|男|90
E|1|男|80
F|2|女|92
G|1|女|95
H|1|男|95
I|3|女|99
J|3|男|99

查看是否加载成功:

hive> select * from tmp_student;
OK
A	345
B	355
C	274
D	390
E	180
F	292
G	195
H	195
I	399
J	399
Time taken: 0.377 seconds, Fetched: 10 row(s)

2、grouping sets示例

数据表有4个字段:姓名、班级、性别、分数。
如果我想按照以下3个粒度汇总:
1、每个班级的平均分数
2、每个性别的平均分数
3、每个班级下不同性别的平均分数
则使用多个sql分别汇总的方案为:

select class, avg(score) from tmp.tmp_student group by class;
select sex, avg(score) from tmp.tmp_student group by sex;
select class, sex, avg(score) from tmp.tmp_student group by class, sex;

而使用1个sql使用grouping sets的方案为:

select
    grouping__id, -- 内置变量,只要使用grouping sets就可以调用
    class,
    sex,
    avg(score) as avg_score
from
    tmp.tmp_student
group by
    class,
    sex 
grouping sets(
    class, 
    sex,
    (class, sex)
)

结果为:
Hive之grouping sets用法及grouping_id计算方法_第1张图片
可以看到,使用 grouping sets 同时汇总出了 3 种不同粒度的平均分数。
注意:
1、grouping sets 只能用于 group by 之后。
2、grouping sets 中可以包含多种粒度,粒度之间用逗号连接。
3、grouping sets 中的所有字段,都必须出现在 group by 中,相当于 group by 后面的字段是最细粒度。
4、如果 select 中的字段,没有包含在某个 grouping set 中,那么这个粒度下的这个字段值为 NULL。
4、不同的粒度,可以使用内置变量 grouping__id 进行区分。

grouping_id计算方法

grouping sets 中的每一种粒度,都对应唯一的 grouping__id 值,其计算公式与 group by 的顺序、当前粒度的字段有关。
具体计算方法如下:

  1. 将 group by 的所有字段 倒序 排列。
  2. 对于每个字段,如果该字段出现在了当前粒度中,则该字段位置赋值为1,否则为0。
  3. 这样就形成了一个二进制数,这个二进制数转为十进制,即为当前粒度对应的 grouping__id。

以上述对 tmp_student 的3种粒度的统计结果为例:
1、group by 的所有字段倒序排列为:sex class
2、对于 3 种 grouping sets,分别对应的二进制数为:

序号 grouping set 给倒序排列的字段(sex class)赋值 对应的十进制(grouping__id 的值)
1 class 01 1
2 sex 10 2
3 class,sex 11 3

这就是上面 grouping sets 的结果中 grouping__id 值的由来。

你可能感兴趣的:(大数据/hive)