2017-07-19 104 views
0

表的当前结构有两列,其类型为整数和json。使用json数据类型的Postgres的递归查询

JSON是非结构化的,它可以有任何嵌套级别。每个JSON文档可以是由level字段指示的父代或子代。 如果levelparent它可以包含另一个parent节点或child节点。 如果levelchild那么它就是JSON的叶节点。

节点的嵌套可以n

我想编写一个查询,在那里我需要用特定条件的所有child节点。

我采取的方法是:

  1. 找到所有child节点的所有子节点
  2. 的recursively.Basically扁平结构,那么做这些child节点上的投影。

这种情况的样表可以在这里找到: SqlFiddleLink

它上面使用的JSON可以在这里找到: Sample JSON Structure

查询我写的作品时,孩子的水平只是一个级别,但它不适用于嵌套直到水平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具有嵌套的结构级别,它只是返回父元素,我期望它返回子节点。

回答

0

递归应基于列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)  
+0

这个工作到任何嵌套级别。看着此之后,实际上我理解 '''WITH RECURSIVE T(N)AS( SELECT 1 UNION ALL 选择N + 1 FROM吨 ) 选择N FROM吨LIMIT 100;''' –