您现在的位置是:首页 >其他 >GROUPING__ID函数在Spark SQL与Hive中返回差异对比网站首页其他

GROUPING__ID函数在Spark SQL与Hive中返回差异对比

辛友 2025-02-23 12:01:02
简介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’)255011111111255011111111
(‘2023-11-01’,f.is_global_white)127001111111254011111110
(‘2023-11-01’,f.is_global_white, a.channel_level_one)63000111111126001111110
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two)3100001111163000111110
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two,a.channel_resource)1500000111130000011110
(‘2023-11-01’,f.is_global_white, a.channel_level_one,a.channel_level_two,a.channel_resource,a.event_name)7000000011114000001110

测试

测试表及数据如下

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’)3131
(‘2023-11-13’,f1)1515
(‘2023-11-13’,f1,f2)77
(‘2023-11-13’,f1,f2,f3))33
(‘2023-11-13’,f1,f2,f3,f4))11
(‘2023-11-13’,f1,f2,f4,f4,f5)00

可以看到,在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’)3101111131011111
(‘2023-11-13’,f1)1500111115001111
(‘2023-11-13’,f1,f5)700011114001110
(‘2023-11-13’,f1,f5,f2)30000116000110
(‘2023-11-13’,f1,f5,f2,f4))10000014000100

由此测试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的顺序来判断字段是否出现。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。