如何编写递归的SELECT语句

时间:2019-11-12 12:17:24

标签: sql postgresql recursive-query

我有一些书的ID表。该表称为前传,有两列:“ resid”和“ prequelid”。如果此表中的一行ID是一对ID,则表示“前传”值是“残”值的前传。如何为每个书系列编写一个查询,以正确的顺序连接该书系列中的所有前传/续集?示例:《指环王》系列中的书籍具有以下ID:B1002,B1003,B1004。我希望该系列的行看起来像这样(一列称为系列):B1002 => B1003 => B1004

也许这可以递归完成吗?使用CONCAT()吗?请记住,我使用的是Postgres,语法可能与MySQL或SQL Server不同。

有人可以写一个执行此操作的查询吗? ID具有定义的域CHAR(5)。假设没有一本书可以有多个前传。


 resid | prequelid
-------+-----------
 B1003 | B1002
 B1004 | B1003
 B5002 | B5001
 B5003 | B5002
 B5004 | B5003
 B5005 | B5004
 B5006 | B5005
 B5007 | B5006
(8 rows)

在这种情况下,查询结果中将有2行。一排3本书(指环王系列),另一排7本书(哈利波特系列)

1 个答案:

答案 0 :(得分:0)

我认为这可以满足您的要求

with recursive cte as
      (select b.prequelid, b.resid, b.prequelid || '=>' || b.resid as path, 1 as lev
       from books b
       where not exists (select 1 from books b2 where b2.resid = b.prequelid)
       union all
       select cte.prequelid, b.resid, path || '=>' || b.resid, lev + 1
       from cte join
            books b
            on cte.resid = b.prequelid
       where lev < 5
      )
select distinct on (prequelid) *
from cte
order by prequelid, lev desc;

Here是db <>小提琴。