hive读取json数组并转换成多行(列转行)

这篇博客介绍了如何在Hive中处理包含JSON数组的字段,将数组内容拆分成多行。通过数据清洗、替换间隔符、split操作及lateral view explode函数的使用,实现了将JSON数组转换为单独的行记录。
背景:在读取hive表中某一些字段的时候,有的json字符串其中会包括数组,那么想要读取这个数组并且转换为多行该怎么操作那?
操作:
1、数据举例:
["[{\"pet_skill_avg_level\":0,\"pet_guard_star\":0,\"pet_type\":0,\"pet_step\":0,\"pet_skill_num\":0,\"pet_adv_score\":0,\"pet_level\":0,\"pet_fight_star\":0,\"pet_id\":\"0\"},{\"pet_skill_avg_level\":0,\"pet_guard_star\":0,\"pet_type\":0,\"pet_step\":0,\"pet_skill_num\":0,\"pet_adv_score\":0,\"pet_level\":0,\"pet_fight_star\":0,\"pet_id\":\"0\"},{\"pet_skill_avg_level\":0,\"pet_guard_star\":0,\"pet_type\":0,\"pet_step\":0,\"pet_skill_num\":0,\"pet_adv_score\":0,\"pet_level\":0,\"pet_fight_star\":0,\"pet_id\":\"0\"},{\"pet_skill_avg_level\":0,\"pet_guard_star\":0,\"pet_type\":0,\"pet_step\":0,\"pet_skill_num\":0,\"pet_adv_score\":0,\"pet_level\":0,\"pet_fight_star\":0,\"pet_id\":\"0\"},{\"pet_skill_avg_level\":0,\"pet_guard_star\":0,\"pet_type\":0,\"pet_step\":0,\"pet_skill_num\":0,\"pet_adv_score\":0,\"pet_level\":0,\"pet_fight_star\":0,\"pet_id\":\"0\"}]"]

这是其中一个字段的json串,格式是一个数组
在这里插入图片描述
最终想要的是数组中的五条数据分成五行。
实现方法:

SELECT
    col
FROM
    (
        select
            split(
                regexp_replace(regexp_extract(params ['pet_info'],'^\\[(.+)\\]$',1 ), 
                '\\}\\,\\{', '\\}\\|\\|\\{'),
                '\\|\\|'
            ) AS pet_info
        from
            db_a.dwd_event_log
        where
            p_date = '${DATE}'
            and app_id = 165018
            and event = 'pet_flow'
            -- 只取一条进行查询
        LIMIT 1
    ) info lateral view explode(info.pet_info) ss as col

步骤解释:
1、regexp_extract(params ['pet_info'],'^\\[(.+)\\]$',1
将该字段的数据 清洗成这个格式

{"pet_skill_avg_level":0,"pet_guard_star":0,"pet_type":0,"pet_step":0,"pet_skill_num":0,"pet_adv_score":0,"pet_level":0,"pet_fight_star":0,"pet_id":"0"},{"pet_skill_avg_level":0,"pet_guard_star":0,"pet_type":0,"pet_step":0,"pet_skill_num":0,"pet_adv_score":0,"pet_level":0,"pet_fight_star":0,"pet_id":"0"},{"pet_skill_avg_level":0,"pet_guard_star":0,"pet_type":0,"pet_step":0,"pet_skill_num":0,"pet_adv_score":0,"pet_level":0,"pet_fight_star":0,"pet_id":"0"},{"pet_skill_avg_level":0,"pet_guard_star":0,"pet_type":0,"pet_step":0,"pet_skill_num":0,"pet_adv_score":0,"pet_level":0,"pet_fight_star":0,"pet_id":"0"},{"pet_skill_avg_level":0,"pet_guard_star":0,"pet_type":0,"pet_step":0,"pet_skill_num":0,"pet_adv_score":0,"pet_level":0,"pet_fight_star":0,"pet_id":"0"}

2、将上面的格式每个之间的间隔符换成 ‘||’ (注意转义)
3、用 split 将字符串拆分成数组
4、用 lateral view explode 行转列,转换成多行
效果:
在这里插入图片描述

Hive 中,把数组拆分成多行可以使用 `explode` 函数和 `LATERAL VIEW` 结合的方法。以下为具体介绍: ### 基本使用场景 若有一个表 `user_hobbies`,其中包含 `user_id` 和 `hobbies` 字段,`hobbies` 是一个数组类型,存储了用户的多个爱好。 ```sql -- 创建表 CREATE TABLE user_hobbies ( user_id INT, hobbies ARRAY<STRING> ); -- 插入示例数据 INSERT INTO user_hobbies VALUES (1, array('reading', 'swimming', 'running')), (2, array('painting', 'dancing')); -- 使用 explode 函数拆分 hobbies 数组 SELECT user_id, hobby FROM user_hobbies LATERAL VIEW explode(hobbies) hobby_table AS hobby; ``` 在上述代码中,`LATERAL VIEW explode(hobbies) hobby_table AS hobby` 会将 `hobbies` 数组拆分成多行,每行包含一个爱好,同时保留对应的 `user_id`。 ### 解析 JSON 数组拆分成多行数据JSON 数组时,需要先对 JSON 进行处理。数据存在表 `dev.woods_test` 中,解析 JSON 将一行拆分成多行的 SQL 如下: ```sql SELECT a_json FROM ( SELECT split(regexp_replace(regexp_extract (json_col ,'(\\[)(.*?)(\\])',2),'\\},\\{','\\}|\\{'),'\\|') AS a_list FROM dev.woods_test ) a LATERAL VIEW explode(a_list) a_list_tab AS a_json; ``` 这里先通过 `regexp_extract` 提 JSON 数组内容,再使用 `regexp_replace` 替换特定字符,最后用 `split` 分割成数组,再用 `explode` 拆分成多行 [^2]。 ### 两数组转换多行 两个都是数组形式,且是对应关系,需要转换成多行才能按部门维度统计,示例如下: ```sql SELECT t1.*,dept_id1 AS level1_dept_id,dept_name2 AS level1_dept_name FROM ( SELECT * FROM dwd_ins_order_plan_line_info WHERE dt='2023-01-28' ) t1 LATERAL VIEW posexplode(split(order_type_department_id,',')) t AS dept_index1,dept_id1 LATERAL VIEW posexplode(split(order_type_department_name,',')) s AS dept_index2,dept_name2 WHERE dept_index1=dept_index2; ``` 这里使用 `posexplode` 函数,它不仅拆分数组,还会返回元素的位置索引,通过 `where` 子句确保两数组元素位置对应 [^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值