您现在的位置是:首页 >其他 >GROUPING__ID函数在Spark SQL与Hive中返回差异对比网站首页其他
GROUPING__ID函数在Spark SQL与Hive中返回差异对比
简介GROUPING__ID函数在Spark SQL与Hive中返回差异对比
背景
在做离线任务使用Spark引擎与Hive引擎数据对比校验时发现,针对于grouping__id同样的字段,Spark引擎返回值与Hive引擎不同,具体返回值及对应的二进制情况如下
--原任务group by字段
'2023-11-01',
a.channel_level_one,
a.channel_level_two,
a.channel_resource,
a.event_name,
e.tel_province,
e.tel_city,
g.city_tier,
f.is_global_white
group set字段 | 十进制grouping__id(Spark) | 二进制grouping__id(Spark) | 十进制grouping__id(Hive) | 二进制grouping__id(Hive) |
---|---|---|---|---|
(‘2023-11-01’) | 255 | 011111111 | 255 | 011111111 |
(‘2023-11-01’,f.is_global_white) | 127 | 001111111 | 254 | 011111110 |
(‘2023-11-01’,f.is_global_white, a.channel_level_one) | 63 | 000111111 | 126 | 001111110 |
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two) | 31 | 000011111 | 63 | 000111110 |
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two,a.channel_resource) | 15 | 000001111 | 30 | 000011110 |
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two,a.channel_resource,a.event_name) | 7 | 0000000111 | 14 | 000001110 |
测试
测试表及数据如下
create table tmp.grouping_test1(f1 string,f2 string,f3 string,f4 string,f5 string);
insert overwrite tmp.grouping_test1 values('AA1','BB1','CC1','DD1','FF1');
insert into tmp.grouping_test1 values('AA2','BB2','CC2','DD2','FF2');
insert into tmp.grouping_test1 values('AA3','BB3','CC3','DD3','FF3');
insert into tmp.grouping_test1 values('AA4','BB4','CC4','DD4','FF4');
测试SQL1
首先测试sql1,将group by字段依次递增
select '2023-11-13',f1,f2,f3,f4,f5,grouping__id
from tmp.grouping_test2
group by '2023-11-13',f1,f2,f3,f4,f5
grouping sets
(('2023-11-13'),
('2023-11-13',f1),
('2023-11-13',f1,f2),
('2023-11-13',f1,f2,f3),
('2023-11-13',f1,f2,f3,f4),
('2023-11-13',f1,f2,f3,f4,f5));
sql1返回结果如下
group set字段 | 十进制grouping__id(Spark) | 十进制grouping__id(Hive) |
---|---|---|
(‘2023-11-13’) | 31 | 31 |
(‘2023-11-13’,f1) | 15 | 15 |
(‘2023-11-13’,f1,f2) | 7 | 7 |
(‘2023-11-13’,f1,f2,f3)) | 3 | 3 |
(‘2023-11-13’,f1,f2,f3,f4)) | 1 | 1 |
(‘2023-11-13’,f1,f2,f4,f4,f5) | 0 | 0 |
可以看到,在set顺序与group by顺序相同是,hive与spark的返回结果相同
测试SQL2
接下来测试sql2,group by的字段与sql1相同,不同的是不再按照group by字段的顺序设置set
select '2023-11-13',f1,f2,f3,f4,f5,grouping__id
from tmp.grouping_test2
group by '2023-11-13',f1,f2,f3,f4,f5
grouping sets
(('2023-11-13'),
('2023-11-13',f1),
('2023-11-13',f1,f5),
('2023-11-13',f1,f5,f2),
('2023-11-13',f1,f5,f2,f4));
sql2返回结果如下
group set字段 | 十进制grouping__id(Spark) | 二进制grouping__id(Spark) | 十进制grouping__id(Hive) | 二进制grouping__id(Hive) |
---|---|---|---|---|
(‘2023-11-13’) | 31 | 011111 | 31 | 011111 |
(‘2023-11-13’,f1) | 15 | 001111 | 15 | 001111 |
(‘2023-11-13’,f1,f5) | 7 | 000111 | 14 | 001110 |
(‘2023-11-13’,f1,f5,f2) | 3 | 000011 | 6 | 000110 |
(‘2023-11-13’,f1,f5,f2,f4)) | 1 | 000001 | 4 | 000100 |
由此测试sql可见,当set顺序与group by顺序不同时两种引擎的返回结果才会不同,spark会将set字段前置,不在set中的字段放到最后,按照调整后的顺序判断,当字段出现为0,没出现为1;而hive则是按照group by的顺序判断,当字段出现为0,没出现为1;
总结
由上面两个测试结果可以确定,hive和spark的0、1判断逻辑相同,都是当字段在set中存在为0,不存在为1。不同的是spark会调整字段顺序,将不在set中出现的字段全部放到最后,按照新的逻辑判断后返回grouping__id的值,而hive则是完全按照group by的顺序来判断字段是否出现。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。