问题
Requirement: Parse JSON values into rows
JSON:
{
"uid":"2EDA9DC1D4",
"m_lg_loc": "ml_0_49_2965_12990434_1450,ml_0_49_2965_12991888_1450,ml_0_49_2965_12997254_682,ml_0_49_2965_12997940_453",
"codec": "PMMMU,G726-32,PMMMA,A729a,tel",
"trv_dev": "1,10,2",
"geoipp": {
"area_code": 703,
"location": [
-77.2223,
38.94990000014
]
}
}
Expected Output:
Need m_lg_loc
multiple values into rows
ml_0_49_2965_12990434_1450
ml_0_49_2965_12991888_1450
ml_0_49_2965_12997254_682
ml_0_49_2965_12997940_453
Similarly for
codec
PMMMU
G726-32
PMMMA
A729a
tel
location
-77.2223
38.94990000014
Tried:
select JSON_EXTRACT_PATH_TEXT($1, uid) as uid
,JSON_EXTRACT_PATH_TEXT($1, 'm_lg_loc') as m_lg_loc
from /path/abc.json (FILE_FORMAT=>JSON_FORMAT)
回答1:
You can use SPLIT_TO_TABLE to do what you want. Here's an example:
create temporary table foo(v variant);
insert into foo select parse_json(' {
"uid":"2EDA9DC1D4",
"m_lg_loc": "ml_0_49_2965_12990434_1450,ml_0_49_2965_12991888_1450,ml_0_49_2965_12997254_682,ml_0_49_2965_12997940_453",
"codec": "PMMMU,G726-32,PMMMA,A729a,tel",
"trv_dev": "1,10,2",
"geoipp": {
"area_code": 703,
"location": [
-77.2223,
38.94990000014
]
}
}');
--Parse the property as a string.
select v:m_lg_loc::string from foo;
--Split to table
select * from foo, table(SPLIT_TO_TABLE(v:m_lg_loc::string, ','));
--Get and alias the column(s) you want
select "VALUE" as MY_COLUMN from foo, table(SPLIT_TO_TABLE(v:m_lg_loc::string, ','));
回答2:
You can do this all in one step using a LATERAL FLATTEN:
WITH x AS (
SELECT parse_json('{
"uid":"2EDA9DC1D4",
"m_lg_loc": "ml_0_49_2965_12990434_1450,ml_0_49_2965_12991888_1450,ml_0_49_2965_12997254_682,ml_0_49_2965_12997940_453",
"codec": "PMMMU,G726-32,PMMMA,A729a,tel",
"trv_dev": "1,10,2",
"geoipp": {
"area_code": 703,
"location": [
-77.2223,
38.94990000014
]
}
}') as js)
SELECT js:uid::varchar, js:m_lg_loc::varchar, y.value::varchar
FROM x,
LATERAL FLATTEN(INPUT => split(x.js:m_lg_loc::varchar,',')) y;
来源:https://stackoverflow.com/questions/63194545/parse-json-multiple-values-into-rows