使用postgreSQL进行递归查询

时间:2017-05-15 10:19:07

标签: sql postgresql

我的数据库包含数据(例如图像),这个数据可以通过程序修改(例如图像处理),所以我得到了一个从另一个派生的新图像,这个图像也可以修改等等。

2图像也可用于创建新图像,例如:图像a +图像b =图像c

所以在我的dataBase中,我有一个表格“Derived from”,它包含2列(previous_id,new_id),previous_id是图像处理前的图像,new_id是结果。所以我可以像这样有一个“改变历史”:

+------------------+------------------+
| id_previous      | id_new           |
+------------------+------------------+
| a                | c                |
| b                | c                |
| c                | d                |
| d                | e                |
+------------------+------------------+

所以我的问题是:

是否可以使递归查询具有数据ID的所有历史记录?

这样的事情:

Select * from derived_from where id_new = 'e'

应该返回(d,c,b,a)

感谢您的帮助

2 个答案:

答案 0 :(得分:3)

是的,您可以使用recursive CTE

来实现这一目标
with recursive r as (
    select id_previous
    from   derived_from
    where  id_new = 'e'
  union
    select d.id_previous
    from   derived_from d
    join   r on id_new = r.id_previous
)
select id_previous
from   r

http://rextester.com/NZKT73800

备注

  • UNION即使有循环也可以停止递归。使用UNION ALL,您应该自己处理循环,除非您确实确定没有循环。
  • 这将为您提供单独的行(每个“上升”一行)。您也可以聚合它,但它通常比逗号分隔的列表或数组更容易使用。

答案 1 :(得分:1)

您可以使用递归CTE:

with recursive cte as (
      select df.id_new, df.id_previous as parent
      from derived_from df
      where df.id_new = 'e'
      union all
      select cte.id_new, df.id_previous
      from cte join
           derived_from df
           on cte.parent = df.id_new
     )
select id_new, array_agg(parent)
from cte
group by id_new;