【问题标题】:recursive query postgres12 gives [42P19] ERROR递归查询 postgres12 给出 [42P19] 错误
【发布时间】:2020-05-19 11:50:00
【问题描述】:

我正在使用一些父/子玩具辛普森一家数据在 postgres postgres 12 中学习递归。

这里是创建语句:

create table Parent(
    parent varchar,
    child varchar
);

insert into Parent (parent, child) values
                                          ('homer', 'bart'),
                                          ('homer', 'lisa'),
                                          ('marge', 'bart'),
                                          ('marge', 'lisa'),
                                          ('abe', 'homer'),
                                          ('ape', 'abe');

现在我想创建一个表,其中有一列用于祖先,一列用于后代,应如下所示:

ancestor | descendant
----------------------
homer    | bart
homer    | lisa
marge    | bart
marge    | lisa
abe      | homer
ape      | abe
ape      | homer
abe      | bart
abe      | lisa
ape      | bart
ape      | lisa

我的解决方案产生了这个错误:

[42P19] ERROR: recursive reference to query "ancestor" must not appear more than once

这是我的代码:

with recursive
Ancestor(ancestor, descendant) as
    ((select parent, child from Parent)
     union
     (select a1.ancestor, a2.descendant
      from Ancestor a1, Ancestor a2
      where a1.descendant = a2.ancestor))
select *
from Ancestor;

我理解错误,但我不明白如何在不使用祖先与自身的叉积创建中间表的情况下实现我想要的。

【问题讨论】:

    标签: sql postgresql common-table-expression recursive-query


    【解决方案1】:

    通常在递归 CTE 中,您连接到 原始 表,而不是自连接到递归表。

    如果你这样做,你会得到你想要的:

    with recursive Ancestor(ancestor, descendant) as (
          select parent, child
          from Parent
          union all
          select a.ancestor, p.child
          from Ancestor a join
               parent p
               on a.descendant = p.parent
         )
    select *
    from Ancestor;
    

    Here 是一个 dbfiddle。

    【讨论】:

      【解决方案2】:

      您需要将父表加入 CTE:

      with recursive Ancestor as (
        select parent, child 
        from Parent
        where parent = 'abe'
      
        union
      
        select p.parent, p.child
        from parent p
           join ancestor a on a.child = p.parent
      )
      select *
      from Ancestor;
      

      【讨论】:

        猜你喜欢
        • 2013-06-18
        • 2018-08-08
        • 2015-02-13
        • 1970-01-01
        • 2021-11-14
        • 1970-01-01
        • 1970-01-01
        • 2014-11-19
        • 1970-01-01
        相关资源
        最近更新 更多