Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在复杂的层次结构上使用递归_Sql_Postgresql_Recursion - Fatal编程技术网

Sql 在复杂的层次结构上使用递归

Sql 在复杂的层次结构上使用递归,sql,postgresql,recursion,Sql,Postgresql,Recursion,我尝试将递归用于非常复杂的层次结构,如下所示: Root | Second | Third | Leaf with recursive relations as (select parent_id, child_id, 1 as h_level, array[parent_id,child_id] as fullpath from public.entity_relations where parent_type = 4 union all

我尝试将递归用于非常复杂的层次结构,如下所示:

Root    
|    
Second   
|   
Third   
|   
Leaf   
with recursive relations as 
(select parent_id, child_id, 1 as h_level, array[parent_id,child_id] as fullpath
 from public.entity_relations where parent_type = 4
union all 
 select c.parent_id, c.child_id, p.h_level+1, p.fullpath || c.child_id 
 from public.entity_relations c join relations p on p.child_id = c.parent_id)
select * from relations;
但如果没有第二个,也可能是这样:

Root       
|   
Third   
|   
Leaf
我的SQL查询如下所示:

Root    
|    
Second   
|   
Third   
|   
Leaf   
with recursive relations as 
(select parent_id, child_id, 1 as h_level, array[parent_id,child_id] as fullpath
 from public.entity_relations where parent_type = 4
union all 
 select c.parent_id, c.child_id, p.h_level+1, p.fullpath || c.child_id 
 from public.entity_relations c join relations p on p.child_id = c.parent_id)
select * from relations;
下面是一个带有关系表和递归查询的SQLFIDLE链接:

问题是递归返回这个层次结构的子路径。 我只对每个层次结构的最完整路径感兴趣,在本例中,仅对以下记录感兴趣:

BB  CC  2   A,BB,CC
C   D   3   A,B,C,D
注意:我知道子路径对于递归是必要的,
因此,我正在寻找一种在递归之后过滤掉冗余记录的方法

在最终查询中,您只能选择没有子节点的叶子节点:

with recursive relations as (
    select 
        parent_id, 
        child_id, 
        1 as h_level, 
        array[parent_id,child_id] as fullpath
    from entity_relations where parent_type = 4
union all 
    select 
        c.parent_id, 
        c.child_id, 
        p.h_level+1, 
        p.fullpath || c.child_id 
    from entity_relations c 
    join relations p on p.child_id = c.parent_id
)
select *
from relations r
where not exists (
    select from entity_relations e
    where e.parent_id = r.child_id
)

 parent_id | child_id | h_level | fullpath
-----------+----------+---------+-----------
 C         | D        |       2 | {A,C,D}
 BB        | CC       |       2 | {A,BB,CC}
 C         | D        |       3 | {A,B,C,D}
(3 rows)
事实证明,有两条路径通向叶D。您可以根据级别选择其中一条路径

...
select distinct on (child_id) *
from relations r
where not exists (
    select from entity_relations e
    where e.parent_id = r.child_id
)
order by child_id, h_level desc

 parent_id | child_id | h_level | fullpath
-----------+----------+---------+-----------
 BB        | CC       |       2 | {A,BB,CC}
 C         | D        |       3 | {A,B,C,D}
(2 rows)    

在最终查询中,只能选择没有子节点的叶子节点:

with recursive relations as (
    select 
        parent_id, 
        child_id, 
        1 as h_level, 
        array[parent_id,child_id] as fullpath
    from entity_relations where parent_type = 4
union all 
    select 
        c.parent_id, 
        c.child_id, 
        p.h_level+1, 
        p.fullpath || c.child_id 
    from entity_relations c 
    join relations p on p.child_id = c.parent_id
)
select *
from relations r
where not exists (
    select from entity_relations e
    where e.parent_id = r.child_id
)

 parent_id | child_id | h_level | fullpath
-----------+----------+---------+-----------
 C         | D        |       2 | {A,C,D}
 BB        | CC       |       2 | {A,BB,CC}
 C         | D        |       3 | {A,B,C,D}
(3 rows)
事实证明,有两条路径通向叶D。您可以根据级别选择其中一条路径

...
select distinct on (child_id) *
from relations r
where not exists (
    select from entity_relations e
    where e.parent_id = r.child_id
)
order by child_id, h_level desc

 parent_id | child_id | h_level | fullpath
-----------+----------+---------+-----------
 BB        | CC       |       2 | {A,BB,CC}
 C         | D        |       3 | {A,B,C,D}
(2 rows)    

如果我理解正确,您希望:

with recursive relations as (
      select parent_id, child_id, 1 as h_level, array[parent_id,child_id] as fullpath
      from public.entity_relations
      where parent_type = 4
      union all 
      select c.parent_id, c.child_id, p.h_level+1, p.fullpath || c.child_id 
      from public.entity_relations c join
           relations p
           on p.child_id = c.parent_id
     )
select r.*
from relations r
where not exists (select 1
                  from relations r2
                  where r2.fullpath @> r.fullpath and
                        r2.fullpath <> r.fullpath
                 );

如果我理解正确,您希望:

with recursive relations as (
      select parent_id, child_id, 1 as h_level, array[parent_id,child_id] as fullpath
      from public.entity_relations
      where parent_type = 4
      union all 
      select c.parent_id, c.child_id, p.h_level+1, p.fullpath || c.child_id 
      from public.entity_relations c join
           relations p
           on p.child_id = c.parent_id
     )
select r.*
from relations r
where not exists (select 1
                  from relations r2
                  where r2.fullpath @> r.fullpath and
                        r2.fullpath <> r.fullpath
                 );

您希望返回什么结果集?您希望返回什么结果集?