请参见代码中的注释。要转换为映射的字符串数组是由
split(user_info, '(?<=\\}) *, *(?=\\{)')
with mydata as
(select 1 as user_id, '[{"field":"name", "value":"Bob"}, {"field":"gender", "value":"M"}]' as user_info
union all
select 2 as user_id, '[{"field":"gender", "value":"F"}, {"field":"age", "value":22}, {"field":"name", "value":"Ana"}]' as user_info
)
select user_id,
--build new map
str_to_map(concat('name:', name, nvl(concat(',','gender:', gender),''), nvl(concat(',','age:', age),'') )) as user_info
from
(
select user_id,
--get name, gender, age, aggregate by user_id
max(case when user_info['field'] = 'name' then user_info['value'] end) name,
max(case when user_info['field'] = 'gender' then user_info['value'] end) gender,
max(case when user_info['field'] = 'age' then user_info['value'] end) age
from
(
select s.user_id,
--remove {} and ", convert to map
str_to_map(regexp_replace(e.element,'^\\{| *"|\\}$','')) as user_info
from
(
select user_id, regexp_replace(user_info, '^\\[|\\]$','') as user_info -- remove []
from mydata
)s lateral view outer explode(split(user_info, '(?<=\\}) *, *(?=\\{)'))e as element --split by comma between }{ with optional spaces in between
) s
group by user_id
)s
结果:
user_id user_info
1 {"name":"Bob","gender":"M"}
2 {"name":"Ana","gender":"F","age":"22"}