我正在尝试将JSON字符串及其值对解析为表。
这是JSON字符串:
{
"route": {
"coding": [
{
"code": "56",
"display": "ORAL",
"userSelected": true
}
]
}
}
我的目标是将其放入这样的表中:
| parent | key | value | type |
-------------------------------
| null | route | {coding: [...]} | object |
| route | coding | [{"code": "56", ...}] | array |
| route | coding | {"code": "56", ...} | object |
| coding | code | 56 | integer |
| coding | display | ORAL | text |
| coding | userselected | true | boolean |
我正在努力进行递归调用。我能够解析数组或对象,但我只是无法弄清楚如何根据类型调用一个或另一个。
这是我当前的代码:
WITH RECURSIVE temp (parent, key, value, type) AS (
SELECT parent, key, value, type
FROM t1
UNION ALL
SELECT parent, key, value, jsonb_typeof(value) AS type
FROM (
SELECT key AS parent, (jsonb_each(value)).*
FROM temp
WHERE temp.type = 'object') AS p1
), temp2 (parent, key, value, type) AS (
SELECT parent, key, value, type
FROM t1
UNION ALL
SELECT parent, key, jsonb_array_elements(value), 'object' AS type
FROM temp2
WHERE temp2.type = 'array'
)
SELECT parent, key, value, type FROM temp;
任何帮助将不胜感激。谢谢。
答案 0 :(得分:2)
In this answer,您可以找到一个查询,该查询从jsonb对象提取路径。可以很容易地对其进行修改以获得预期的输出:
with recursive extract_all as
(
select
null as parent,
key,
value,
jsonb_typeof(value) as type
from my_table
cross join lateral jsonb_each(jdata)
union all
select
key,
coalesce(obj_key, (arr_key- 1)::text),
coalesce(obj_value, arr_value),
jsonb_typeof(coalesce(obj_value, arr_value))
from extract_all
left join lateral
jsonb_each(case jsonb_typeof(value) when 'object' then value end)
as o(obj_key, obj_value)
on jsonb_typeof(value) = 'object'
left join lateral
jsonb_array_elements(case jsonb_typeof(value) when 'array' then value end)
with ordinality as a(arr_value, arr_key)
on jsonb_typeof(value) = 'array'
where obj_key is not null or arr_key is not null
)
select *
from extract_all;
结果:
parent | key | value | type
--------+--------------+---------------------------------------------------------------------+---------
| route | {"coding": [{"code": 56, "display": "ORAL", "userSelected": true}]} | object
route | coding | [{"code": 56, "display": "ORAL", "userSelected": true}] | array
coding | 0 | {"code": 56, "display": "ORAL", "userSelected": true} | object
0 | code | 56 | number
0 | display | "ORAL" | string
0 | userSelected | true | boolean
(6 rows)
请注意,数组元素没有键,因此我们应该使用它们的索引来标识它们。正式而言,coding
不是嵌套数组元素的父级。