Reputation: 369
How could I extract the values in keys and array on json
json
{
"key1": "US",
"key2": "545644566",
"car": ["HONDA","TOYOTA","FORD"]
}
The resulted expected:
key | value |
---|---|
key1 | US |
key2 | 545644566 |
car | HONDA |
car | TOYOTA |
car | FORD |
I tried using:
SELECT JSON_EXTRACT(u.json, CONCAT('$.','"',g.field_name,'"')),g.*
FROM table_json u
LEFT JOIN table_column g
ON JSON_CONTAINS(JSON_KEYS(u.json), JSON_QUOTE(g.field_name), '$')
Upvotes: 1
Views: 205
Reputation: 65198
You can use a dictionary table such as information_schema.tables
along with iterating index values for some variables in order to generate rows for the elements of the arrays. The following code also works for non-array elements without need of a conditional. Apply JSON_KEYS()
function to derive the key elements in the first subquery, and then use JSON_EXTRACT()
for the respective indexes to derive the corresponding values of the arrays in the last subquery such as
WITH t1 AS
(
SELECT @i := @i + 1 AS i,
JSON_UNQUOTE(JSON_EXTRACT(kys, CONCAT('$[', @i - 1, ']'))) AS `key`,
JSON_EXTRACT(json,
CONCAT('$.',
JSON_EXTRACT(kys, CONCAT('$[', @i - 1, ']'))
)
) AS value, kys
FROM t
JOIN (SELECT @i := 0, JSON_KEYS(json) AS kys FROM t) AS k
JOIN information_schema.tables
)
SELECT @k := IF(@j=`key`,@k + 1,0) AS `index`,
@j := `key` AS `key`,
JSON_UNQUOTE(JSON_EXTRACT(value, CONCAT('$[', @k, ']'))) AS value
FROM t1
JOIN (SELECT @k := 0 ) AS k
LEFT JOIN information_schema.tables
ON @k < JSON_LENGTH(value) - 1
WHERE value IS NOT NULL
Upvotes: 1