工作中看代码时遇到lateral view explode(split(sni_type,',')) snTable as sni_info ,初看挺一脸懵逼的,细查之后才明白是对字段sni_type进行分割之后,将分割后中的元素值转换为了多行。具体:
split()函数
split()函数用于分割数据。语法格式为split(str,sep) ,参数str为字符串类型的字段,sep为分割符(支持正则),结果返回一个数组array。如上面split(sni_type,',') ,假设字段sni_type的值为“7,17,20,8”,则上述以逗号分割,得到数组['7','17','20','8']。
注意:对于 “.”,"|“这样的特殊字符,不加”\“的时候是特殊字符,加了以后才是普通字符,而对于”\d"的字符,需要加"\“后才是特殊字符,就是是说”\\d"才是匹配数字。
explode 函数
用于将一行转换为多行。维基百科的解释是“explode() takes in an array (or a map) as an input and outputs the elements of the array (map) as separate rows. UDTFs can be used in the SELECT expression list and as a part of LATERAL VIEW.”即将一个为array或者map的字段中的元素分开成为独立的行。
-- 假设sni_type的值为 "25,36,100"
select explode(split(sni_type,",")) as partSni
from ods_up_content_source
where sni_type is not NULL and dt='20210104' and size(split(sni_type,","))>3
limit 10;
--其中的一个返回结果为
25
36
100
lateral view 函数
lateral view 用于将用户生成的数据表进行连接。wiki的解释为:”Lateral view is used in conjunction with user-defined table generating functions such as explode(). As mentioned in Built-in Table-Generating Functions, a UDTF generates zero or more output rows for each input row. A lateral view first applies the UDTF to each row of base table and then joins resulting output rows to the input rows to form a virtual table having the supplied table alias“
初看上去有点不好理解,先看个报错的示例:
即如果直接select只能选择单列,不能选择多个字段。而此时,lateral view就派上用场了,可将多个字段进行连接。
select sni_type,sni_info
from ods_up_content_source
lateral view explode(split(sni_type,',')) snTable as sni_info
where sni_type is not NULL and dt='20210104' and size(split(sni_type,","))>3
limit 10;
结果显示:
实际处理中,select选择的其他的字段的数据会复制。可以看出如果原来是m行个sni_type,每个sni_type都是含n个元素,则新得到的有m*n行。
综上: lateral view用于和split, explode等UDTF一起使用,它能够将一行数据拆成多行数据,在此基础上可以对拆分后的数据进行聚合。lateral view首先为原始表的每行调用UDTF,UDTF会把一行拆分成一或者多行,lateral view再把结果组合,产生一个支持别名表的虚拟表。
鸣谢与参考:
https://blog.csdn.net/yahahassr/article/details/97911676
https://blog.csdn.net/bitcarmanlee/article/details/51926530
https://blog.csdn.net/wangwangstone/article/details/112687431