sql之取出json字符串中指定字段的值

需求如题,取出json字符串中brandName的值。
样本数据:有两个字段:id,brand

id brand
1 [{“brandList”:[{“brandId”:“752”,“brandName”:“xxx752”},{“brandId”:“516”,“brandName”:“xxx516”},{“brandId”:“650”,“brandName”:“xxx650”},{“brandId”:“586”,“brandName”:“xxx586”},{“brandId”:“630”,“brandName”:“xxx630”}],“categoryId”:“542”,“categoryName”:“xxx542”},{“brandList”:[{“brandId”:“752”,“brandName”:“xxx752”},{“brandId”:“650”,“brandName”:“xxx650”}],“categoryId”:“7”,“categoryName”:“xxx7”},{“brandList”:[{“brandId”:“529”,“brandName”:“xxx529”,“seriesList”:[{“seriesId”:“22”,“seriesName”:“xxx22”}]}],“categoryId”:“10”,“categoryName”:“xxx10”}]
2 [{“categoryId”:“9”,“categoryName”:“xxx”,“brandList”:[{“brandId”:“597”,“brandName”:“xxx597”}]},{“categoryId”:“5”,“categoryName”:“xxx”,“brandList”:[{“brandId”:“597”,“brandName”:“xxx597”}]},{“categoryId”:“10”,“categoryName”:“xxx”,“brandList”:[{“brandId”:“529”,“brandName”:“xxx529”,“seriesList”:[{“seriesId”:“22”,“seriesName”:“xxx”}]}]}]

解答思路:

  1. 利用 lateral view explode split 将brand按指定字段名brandName切分,并作为虚拟表的一列brand_name。
  2. 使用brand_name进行按 “:” 字符继续拆分,取出第1条后继续按 “ 拆分取出第0条。
  3. 此时发现上一步结果的每个id组第一行数据不符合要求,是多余信息,根据业务实际场景,此处使用正则表达式,排出字段值等于数字的情况。
  4. 最后将输出收集放到set中,自动去重。
select id, collect_set(split(split(brand_name,'":"')[1],'"')[0]) as brand_name
from json_test
lateral view explode(split(brand,'brandName')) adTable as brand_name
where (split(split(brand_name,'":"')[1],'"')[0] REGEXP '[^0-9.]')!=0
group by id;

输出:

id brand_name
1 [“xxx752”,“xxx516”,“xxx650”,“xxx586”,“xxx630”,“xxx529”]
2 [“xxx597”,“xxx529”]

补充:Hive中常用的两个正则函数
regexp_extract:
语法:regexp_extract(string subject,string pattern,int index)
返回值:string
说明:将字符串subject按照pattern正则表达式的规则拆分,返回指定index的字符
如:

select regexp_extract('apple#orange#banana','([a-z]+)#([a-z]+)#([a-z]+)',2);

regexp_replace:
语法:regexp_replace(string a,string b,string c)
返回值:string
说明:将字符串a中的符合正则表达式b的部分替换成c
如:

select split(regexp_replace('abc123def456','[0-9]+',','),',');

你可能感兴趣的:(sql之取出json字符串中指定字段的值)