具有 json 数据类型的 Postgres 递归查询
Recursive query for Postgres with json datatype
table 的当前结构有两列,其类型为整数和 json。
JSON 是非结构化的,它可以有任何嵌套级别。每个 JSON 文档可以是父文档或子文档,由 level
字段指示。
如果 level
是 parent
,它可以包含另一个 parent
节点或 child
节点。
如果 level
是 child
那么它就是 JSON 的叶节点。
节点嵌套可以n
我正在尝试编写一个查询,其中我需要具有特定条件的所有 child
节点。
我采用的方法是:
- 查找所有
child
个节点recursively.Basically所有子节点的平面结构
- 然后在那些
child
节点上进行投影。
可在此处找到此示例 table:
SqlFiddleLink
上面用到的JSON可以在这里找到:
Sample JSON Structure
我编写的查询在 child 级别只有一级时有效,但不适用于 n
级别的嵌套
一直工作到级别 1 的查询是:
WITH RECURSIVE x ( c ) AS (
Select * from
json_array_elements((select info FROM Controls where ID='111'))c
where c ->>'level' = 'child'
UNION ALL
select json_array_elements(
(
Select parent_control->'controls' controls from
json_array_elements((select info FROM Controls where
ID='111'))parent_control
where parent_control ->>'level' = 'parent'
))
)select c->>'unique_tag' as unique_tag, c ->>'values' as values from x
我可能在这里遗漏了非常小的东西,我正在努力使这项工作直到任何嵌套级别。任何帮助表示赞赏。
在 SqlFiddle 中,我输入了两行。
带有 111
的 ID 具有一层嵌套,查询可与之配合使用。
但是,具有 110
的 ID 具有嵌套级别的结构,它只是 return 的父元素,我希望它是 return 子节点。
递归应该基于value->'controls'
列,在json列显式创建递归结构:
with recursive rec_controls(id, unique_tag, controls, level) as (
select id, value->>'unique_tag', value->'controls', value->>'level'
from controls, json_array_elements(info)
union all
select id, value->>'unique_tag', value->'controls', value->>'level'
from rec_controls, json_array_elements(controls)
)
select id, unique_tag
from rec_controls
where level = 'child'
order by 1, 2;
id | unique_tag
-----+------------
110 | child_1
110 | child_2
110 | child_3
111 | 1
111 | 2
111 | 4
111 | 5
111 | 6
111 | 8
(9 rows)
table 的当前结构有两列,其类型为整数和 json。
JSON 是非结构化的,它可以有任何嵌套级别。每个 JSON 文档可以是父文档或子文档,由 level
字段指示。
如果 level
是 parent
,它可以包含另一个 parent
节点或 child
节点。
如果 level
是 child
那么它就是 JSON 的叶节点。
节点嵌套可以n
我正在尝试编写一个查询,其中我需要具有特定条件的所有 child
节点。
我采用的方法是:
- 查找所有
child
个节点recursively.Basically所有子节点的平面结构 - 然后在那些
child
节点上进行投影。
可在此处找到此示例 table: SqlFiddleLink
上面用到的JSON可以在这里找到: Sample JSON Structure
我编写的查询在 child 级别只有一级时有效,但不适用于 n
一直工作到级别 1 的查询是:
WITH RECURSIVE x ( c ) AS (
Select * from
json_array_elements((select info FROM Controls where ID='111'))c
where c ->>'level' = 'child'
UNION ALL
select json_array_elements(
(
Select parent_control->'controls' controls from
json_array_elements((select info FROM Controls where
ID='111'))parent_control
where parent_control ->>'level' = 'parent'
))
)select c->>'unique_tag' as unique_tag, c ->>'values' as values from x
我可能在这里遗漏了非常小的东西,我正在努力使这项工作直到任何嵌套级别。任何帮助表示赞赏。
在 SqlFiddle 中,我输入了两行。
带有 111
的 ID 具有一层嵌套,查询可与之配合使用。
但是,具有 110
的 ID 具有嵌套级别的结构,它只是 return 的父元素,我希望它是 return 子节点。
递归应该基于value->'controls'
列,在json列显式创建递归结构:
with recursive rec_controls(id, unique_tag, controls, level) as (
select id, value->>'unique_tag', value->'controls', value->>'level'
from controls, json_array_elements(info)
union all
select id, value->>'unique_tag', value->'controls', value->>'level'
from rec_controls, json_array_elements(controls)
)
select id, unique_tag
from rec_controls
where level = 'child'
order by 1, 2;
id | unique_tag
-----+------------
110 | child_1
110 | child_2
110 | child_3
111 | 1
111 | 2
111 | 4
111 | 5
111 | 6
111 | 8
(9 rows)