Я пытаюсь проанализировать вложенный JSON в Postgres, который имеет следующую структуру:
{
"id": 0,
"children": [{
"id": 965,
"children": [{
"id": 967
},
{
"id": 969
},
{
"id": 971
},
{
"id": 973
}
]
},
{
"id": 974,
"children": [{
"id": 976
},
{
"id": 978
}
]
}
]
}
Моя желаемая форма вывода такая:
-------------------------------------------
|parent_id |child_id |
-------------------------------------------
|0 |965 |
|0 |974 |
|965 |967 |
|965 |969 |
|965 |971 |
|965 |973 |
|974 |976 |
|974 |978 |
-------------------------------------------
Я пытаюсьдля этого используйте рекурсивные CTE, однако, что бы я ни пытался, я сталкиваюсь либо с could not identify an equality operator for type json
, либо с ERROR: set-returning functions are not allowed in CASE
.Я могу получить данные для одного уровня, но это далеко от того, что я намерен делать, поэтому любые предложения относительно того, что я мог бы сделать по-другому, были бы очень полезны.
Здесь - это то, как вы можете быстро опробовать его в случае необходимости вместе со всем, что я пробовал, и с ошибками, которые возникли.Также было бы бонусом, если ваши предложения работают на json
и jsonb
оба.
Спасибо
Редактировать: число уровней JSON не фиксировано, оно может быть до любого уровня (максимум 3-4).
Редактировать: добавление запросов, которые я пробовал здесьсамо по себе:
with recursive cte(id,json_element) as (
select tree->'id',tree->'children' from json_test
union
select json_element->'id',json_element->'children' from cte
) select * from cte;
--could not identify an equality operator for type json
WITH RECURSIVE cte(id, children) AS (
SELECT
tree->'id' as id,
tree->'children' as children
FROM json_test
UNION ALL
SELECT
children -> 'id',
children -> 'children'
FROM cte,
--json_each(CASE WHEN json_typeof(cte.children) <> 'object' THEN '{}' :: JSON ELSE cte.children END) AS t
json_each(CASE WHEN json_typeof(cte.children) = 'array' THEN json_array_elements(cte.children) ELSE cte.children END) AS t
)
SELECT * FROM cte WHERE json_typeof(cte.children) <> 'object';
--ERROR: set-returning functions are not allowed in CASE
--Hint: You might be able to move the set-returning function into a LATERAL FROM item.
Я также пытался несколько раз изменить эти запросы, но в итоге получилось с теми же ошибками.