您现在的位置是:首页 >技术交流 >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的顺序来判断字段是否出现。
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。
        
    
        
    
            




U8W/U8W-Mini使用与常见问题解决
QT多线程的5种用法,通过使用线程解决UI主界面的耗时操作代码,防止界面卡死。...
stm32使用HAL库配置串口中断收发数据(保姆级教程)
分享几个国内免费的ChatGPT镜像网址(亲测有效)
Allegro16.6差分等长设置及走线总结