Postgres中的递归SQL查询

时间:2014-08-03 12:10:57

标签: sql postgresql recursive-query

架构:

Person(pid:int,
       name:char(20),
       predecessor:int -> Person.pid
      )

示例表:

pid, name, predecessor
0,   'abc', NULL
1,   'bcd', 0
2,   'cde', 1
3,   'efg', NULL
4,   'fgh', 3

我如何找到一个人'abc'的所有继承人?

期望的输出:

name 
'bcd'
'cde' 

非常感谢!

2 个答案:

答案 0 :(得分:1)

您可以通过生成所有祖先然后将其过滤掉来完成此操作。以下是您的数据示例:

with recursive cte(pid, lev, ancestor) as (
      select pid, 0, predecessor
      from person p 
      union all
      select cte.pid, lev + 1, p.predecessor
      from person p join
           cte
           on p.pid = cte.ancestor
     )
select p2.name
from cte join
     person p1
     on cte.ancestor = p1.pid join
     person p2
     on cte.pid = p2.pid
where p1.name = 'abc';

Here是一个SQL小提琴。

答案 1 :(得分:0)

只需在recursive CTE中生成所需的行(而不是所有行的所有祖先):

with recursive cte as (
   select p.pid, p.name, 1 AS lvl
   from   person a
   join   person p ON p.predecessor = a.pid
   where  a.name = 'abc'

   union all
   select p.pid, p.name, c.lvl + 1
   from   cte    c
   join   person p ON  p.predecessor = c.pid
   )
select name
from   cte
order  by lvl;

SQL Fiddle.

除此之外:You don't want to use char(20). Just use text.