场景:(1)将表中的字段转化成json数组,合并列,然后再合并行。建测试表,1315 、11729为表中某字段的值分属于不同的行,123、456为另一字段的对应行数字。准备测试数据,样例如下:[{"c1":"1315","c2":"123"},{"c1":"11729","c2":"456"}]。(2)将上述样例解析为表中的字段值1315、123。
1.准备测试数据的方法:
1)用:连接
select concat_ws(':','c1',a) from b
结果如下:
c1:1672
c1:5025
c1:12218
……
2)加上双引号
select concat(',',concat('\"','c1','\"'),':',concat('\"',a,'\"')) kv from b
结果如下:
"c1":"1672"
"c1":"5025"
"c1":"12218"
3)加[{
SELECT CONCAT('{[',CONCAT(CONCAT('\"','c1','\"'),':',CONCAT('\"',a,'\"')),',',CONCAT(CONCAT('\"','c2','\"'),':',CONCAT('\"',nvl(b,''),'\"')),']}') FROM c
结果如下:
{["c1":"1672","c2":"14227"]}
{["c1":"12473","c2":""]}
4)合并行(如果有多个字段,将多个字段group,需注意group的字段里面维度不同导致合并不出想要的结果)
SELECT
id,
CONCAT ('[',CONCAT_WS(',',collect_set(kw)),']') AS kw
FROM
(SELECT
medal_id,
CONCAT(
'{'
,CONCAT(
CONCAT(CONCAT('\"', 'c1', '\"'),':',CONCAT('\"', a, '\"')),
',',
CONCAT(CONCAT('\"', 'c2', '\"'),':',CONCAT('\"', nvl (b, ''),'\"')))
,'}') AS kw
FROM a GROUP BY id;
结果如下:
[{"c1":"6233","c2":"6260"},{"c1":"6233","c2":"6264"}]
综上,测试数据准备完成。
2.解析json字符串:
存储的数据类型是string,方法如下:先把[去掉,然后把分隔符编程||,然后一行变多行。
1)去掉[用如下: '^\\[(.+)\\]$',1),'\\}\\,\\{' , 将分隔符改成|| 用如下: '\\}\\|\\|\\{',分别用正则表达式函数regexp_extract(str, regexp[, idx])
select regexp_replace(regexp_extract(dddd,'^\\[(.+)\\]$',1),'\\}\\,\\{', '\\}\\|\\|\\{') as kw from test_002;
结果如下:
{"c1":"12218","c2":""}
{"c1":"13314","c2":""}||{"c1":"9192","c2":""}
2)一行变多行
SELECT a.id,b.kws,c.first,c.second FROM
(SELECT id, split(regexp_replace(regexp_extract(dddd,'^\\[(.+)\\]$',1),'\\}\\,\\{', '\\}\\|\\|\\{'),'\\|\\|') AS kw
FROM test_002 )a
LATERAL VIEW explode(a.kw)b AS kws -----把一行变成多行
LATERAL VIEW json_tuple(b.kws,'c1','c2') c AS c1,c2; --------把c1,c2从字符串中解析出来。
结果如下:
100006 {"c1":"16","c2":"14"} 1672 14227
100006 {"c1":"473","c2":""} 473
2.sql跑和在shell(或者hive -e)执行:hive -e 中执行转义字符\\改成\\\\,试验不可以,然后再修改转义字符\\\\\\,示例如下:
SELECT
id,
split (
regexp_replace (
regexp_extract(cate_condition, '^\\\\\\[(.+)\\\\\\]$', 1),
'\\\\\\}\\\\\\,\\\\\\{','\\\\\\}\\\\\\|\\\\\\|\\\\\\{'
),
'\\\\\\|\\\\\\|'
) AS kw