sqloracle-databasepostgresqlconnect-by

NOCYCLE in Postgres


I have a Oracle query with a NOCYCLE clause which I have to translate to Postgres:

SELECT FG_ID,CONNECT_BY_ROOT FG_ID as Parent_ID  
FROM FG t
START WITH t.Parent_filter_group_id is null 
CONNECT BY NOCYCLE PRIOR t.FILTER_GROUP_ID = t.PARENT_FILTER_GROUP_ID 

I have converted this one with the help of the question and answer in connect_by_root equivalent in postgres

as

with recursive fg_tree as (
select FG_ID,
       FG_ID as fg
from  FG
where Parent_filter_group_id is null 

union all 
select c.FG_ID,
p.fg
from FG c join fg_tree p on p.FG_ID = PARENT_FILTER_GROUP_ID
)
select * from fg_tree
order by FG_ID

but in this there is no clause for NOCYCLE if the parent is also one of the children then this query will return error.


Solution

  • You can collect the IDs for each level and then join on the condition that the "current" id is not contained in the path:

    with recursive fg_tree as (
      select FG_ID,
             FG_ID as fg, 
             array[fg_id] as path
      from  FG
      where Parent_filter_group_id is null 
    
      union all 
    
      select c.FG_ID,
             p.fg, 
             p.fg||c.fg_id
      from FG c 
        join fg_tree p on p.FG_ID and c.fg_id <> ALL (p.path)
    )
    select fg_id, fg 
    from fg_tree
    order by filter_group_id