hive 行转列 lateral view explode

Category 的格式为:mary:5,mike:6

而需要的是前面的名字

手写需要行转列,然后再去每行:前面的内容

select distinct a.dt as dt, a.uid as uid, split(a.category0,'_')[0] as cate1 from 

(select  distinct dt, uid, category0

from t_dw_user_app_list_60days  lateral view explode(split(category, ',')) t1 as category0

where dt= 20180420) a

1.explode

hive wiki对于expolde的解释如下:

explode()接受一个数组(map)作为输入,并将数组(map)的元素作为单独的行输出。 UDTF可以在SELECT表达式列表中使用,也可以用作LATERAL VIEW的一部分。

以下是一个在一个选择语句中用了explode(),这个名为myTable的表有一列(myCol)和两行:

运行此查询语句:

SELECT explode(myCol) AS myNewCol FROM myTable;

结果:
 
在map中的用法类似:

SELECT explode(myMap) AS (myMapKey, myMapValue) FROM myMapTable;

总结起来一句话:explode就是将hive一行中复杂的array或者map结构拆分成多行。

使用实例: 
xxx表中有一个字段mvt为string类型,数据格式如下:

[{“eid”:”38”,”ex”:”affirm_time_Android”,”val”:”1”,”vid”:”31”,”vr”:”var1”},{“eid”:”42”,”ex”:”new_comment_Android”,”val”:”1”,”vid”:”34”,”vr”:”var1”},{“eid”:”40”,”ex”:”new_rpname_Android”,”val”:”1”,”vid”:”1”,”vr”:”var1”},{“eid”:”19”,”ex”:”hotellistlpage_Android”,”val”:”1”,”vid”:”1”,”vr”:”var01”},{“eid”:”29”,”ex”:”bookhotelpage_Android”,”val”:”0”,”vid”:”1”,”vr”:”var01”},{“eid”:”17”,”ex”:”trainMode_Android”,”val”:”1”,”vid”:”1”,”vr”:”mode_Android”},{“eid”:”44”,”ex”:”ihotelList_Android”,”val”:”1”,”vid”:”36”,”vr”:”var1”},{“eid”:”47”,”ex”:”ihotelDetail_Android”,”val”:”0”,”vid”:”38”,”vr”:”var1”}]

用explode小试牛刀一下:

select explode(split(regexp_replace(mvt,'\\[|\\]',''),'\\},\\{')) from ods_mvt_hourly whereday=20160710 limit 10;

最后出来的结果如下: 
{“eid”:”38”,”ex”:”affirm_time_Android”,”val”:”1”,”vid”:”31”,”vr”:”var1” 
“eid”:”42”,”ex”:”new_comment_Android”,”val”:”1”,”vid”:”34”,”vr”:”var1” 
“eid”:”40”,”ex”:”new_rpname_Android”,”val”:”1”,”vid”:”1”,”vr”:”var1” 
“eid”:”19”,”ex”:”hotellistlpage_Android”,”val”:”1”,”vid”:”1”,”vr”:”var01” 
“eid”:”29”,”ex”:”bookhotelpage_Android”,”val”:”0”,”vid”:”1”,”vr”:”var01” 
“eid”:”17”,”ex”:”trainMode_Android”,”val”:”1”,”vid”:”1”,”vr”:”mode_Android” 
“eid”:”44”,”ex”:”ihotelList_Android”,”val”:”1”,”vid”:”36”,”vr”:”var1” 
“eid”:”47”,”ex”:”ihotelDetail_Android”,”val”:”0”,”vid”:”38”,”vr”:”var1”} 
{“eid”:”38”,”ex”:”affirm_time_Android”,”val”:”1”,”vid”:”31”,”vr”:”var1” 
“eid”:”42”,”ex”:”new_comment_Android”,”val”:”1”,”vid”:”34”,”vr”:”var1”

REGEXP_REPLACE 函数把替换功能向前推进了一步,其语法在表中列出。 

语法

说明

REGEXP_REPLACE(source_string, pattern
[, replace_string [, position
[,occurrence, [match_parameter]]]])

该函数用一个指定的 replace_string 来替换匹配的模式,从而允许复杂的"搜索并替换"操作。

 

2.lateral view

hive wiki 上的解释如下:

Lateral view与用户定义的表生成函数(如explode())一起使用。 正如内置表生成函数中所述,UDTF为每个输入行生成零个或多个输出行。 Lateral view首先将UDTF应用于基表的每行,然后将结果输出行连接到输入行以形成具有所提供的表别名的虚拟表。

Example

下面有个名为pageAds.的表,有两列pageid和adid_list

例子:

用户希望统计广告在所有网页上显示的总次数
带explode()的Lateralview可用于使用查询将adid_list转换为单独的行:

SELECT pageid, adid
FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid;

结果如下:
 
然后为了统计特定广告出现的次数,可以使用count / group by:

SELECT adid, count(1)
FROM pageAds LATERAL VIEW explode(adid_list) adTable AS adid
GROUP BY adid;

结果如下:

由此可见,lateralview与explode等udtf就是天生好搭档,explode将复杂结构一行拆成多行,然后再用lateral view做各种聚合。

3.实例

还是第一部分的例子,上面我们explode出来以后的数据,不是标准的json格式,我们通过lateralview与explode组合解析出标准的json格式数据:

SELECT ecrd, CASEWHEN instr(mvtstr,'{')=0
    AND instr(mvtstr,'}')=0 THEN concat('{',mvtstr,'}') WHEN instr(mvtstr,'{')=0
    AND instr(mvtstr,'}')>0 THEN concat('{',mvtstr) WHEN instr(mvtstr,'}')=0
    AND instr(mvtstr,'{')>0 THEN concat(mvtstr,'}') ELSE mvtstr END AS mvt
      FROM ods.ods_mvt_hourly LATERAL VIEW explode(split(regexp_replace(mvt,'\\[|\\]',''),'\\},\\{')) addTable AS mvtstr
        WHERE DAY='20160710' and ecrd is not null limit 10

查询出来的结果: 
xxx 
{“eid”:”38”,”ex”:”affirm_time_Android”,”val”:”1”,”vid”:”31”,”vr”:”var1”} 
xxx 
{“eid”:”42”,”ex”:”new_comment_Android”,”val”:”1”,”vid”:”34”,”vr”:”var1”} 
xxx 
{“eid”:”40”,”ex”:”new_rpname_Android”,”val”:”1”,”vid”:”1”,”vr”:”var1”} 
xxx 
{“eid”:”19”,”ex”:”hotellistlpage_Android”,”val”:”1”,”vid”:”1”,”vr”:”var01”} 
xxx 
{“eid”:”29”,”ex”:”bookhotelpage_Android”,”val”:”0”,”vid”:”1”,”vr”:”var01” 
xxx 
{“eid”:”17”,”ex”:”trainMode_Android”,”val”:”1”,”vid”:”1”,”vr”:”mode_Android”} 
xxx 
{“eid”:”44”,”ex”:”ihotelList_Android”,”val”:”1”,”vid”:”36”,”vr”:”var1”} 
xxx 
{“eid”:”47”,”ex”:”ihotelDetail_Android”,”val”:”1”,”vid”:”38”,”vr”:”var1”} 
xxx 
{“eid”:”38”,”ex”:”affirm_time_Android”,”val”:”1”,”vid”:”31”,”vr”:”var1”} 
xxx 
{“eid”:”42”,”ex”:”new_comment_Android”,”val”:”1”,”vid”:”34”,”vr”:”var1”}

4.Ending

Lateral View通常和UDTF一起出现,为了解决UDTF不允许在select字段的问题。 
Multiple Lateral View可以实现类似笛卡尔乘积。 
Outer关键字可以把不输出的UDTF的空结果,输出成NULL,防止丢失数据。



猜你喜欢

转载自blog.csdn.net/weixin_38987362/article/details/80702388