【问题标题】:Postgre / SQL queries with recursive具有递归的 Postgre / SQL 查询
【发布时间】:2016-01-23 13:24:45
【问题描述】:

我正在尝试创建某个 SQL 查询。首先,这是 ER 图和我创建的表:

CREATE TABLE Course (
    CNr INTEGER PRIMARY KEY NOT NULL,
    costs NUMERIC(7, 2) NOT NULL
);

CREATE TABLE requires (
    pred INTEGER REFERENCES Course(CNr),
    succ INTEGER REFERENCES COURSE(CNr),
    PRIMARY KEY(pred, succ)
);

表格及其值如下所示:

|   Course    |  |   requires  |
|-------------|  |-------------|
| CNr | costs |  | pred | succ |
|-----|-------|  |------|------|
|  1  |  100  |  |  1   |  2   |
|  2  |  200  |  |  1   |  3   |
|  3  |  300  |  |  2   |  3   |
|  4  |  400  |  |  3   |  4   |

我需要的是返回一个课程的 CNr 和它本身的成本加上所有之前课程的总和。对于给定的表格,它应该如下所示:

| CNr | total |
|-----|-------|
|  1  |  100  |
|  2  |  300  |
|  3  |  600  |
|  4  |  1000 |

我省略了循环条目,因为在这种情况下它真的没有意义(如果它们按循环顺序进行,就不能真正完成课程),所以我不确定你是否有也去寻找那个。 这应该可以通过 WITH RECURSIVE 以某种方式实现,但老实说,我很茫然。至少有人能指出我正确的方向吗?

【问题讨论】:

    标签: sql postgresql recursion circular-dependency


    【解决方案1】:

    您可以使用递归 CTE 来做到这一点:

    with recursive cte as (
          select pred, succ
          from requires r
          union all
          select cte.pred, r.succ
          from cte join
               requires r
               on cte.succ = r.pred
         )
    select c.cnr, coalesce(sum(cpred.costs), 0) + c.costs
    from course c left join
         (select distinct * from cte) cte
         on c.cnr = cte.succ left join
         course cpred
         on cte.pred = cpred.cnr
    group by c.cnr, c.costs;
    

    Here 是一个 SQL Fiddle。

    【讨论】:

    • 谢谢!但是,有人可以解释一下 coalesce(sum(cpred.costs), 0) + c.costs 部分发生了什么吗?我想我错过了一些东西。
    • 那只是将当前课程的费用添加到前人的费用中。如果没有,前辈的总和是NULL
    【解决方案2】:

    先试试这个简单的查询,看看你会得到什么:

    SELECT
        CNr
        , COALESCE(
        (
            SELECT SUM( costs )
            FROM Course cr
            WHERE CNr IN (
                SELECT pred 
                FROM requires r
                WHERE r.succ = c.CNr
            )
        )
        , 0 )::INTEGER + costs AS total
    FROM Course c
    

    【讨论】:

    • 谢谢,但是,结果是:1 - NULL 2 - 100 3 - 300 4 - 300
    • 另外 4 应该 = 700 而不是 1000 在你的例子中
    • 4 确实需要 3(总共 600)加上它本身需要的 400。
    • 我刚刚对其进行了编辑,并将合并中的成本更改为 0。它就在那里。保证最后一次你必须尝试。重新复制上面的代码
    • 哦,你的意思是它使用总和。好的,我看看能不能解决这个问题
    猜你喜欢
    • 2015-05-05
    • 1970-01-01
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2020-11-27
    • 2015-07-13
    • 2014-12-19
    • 2012-12-05
    相关资源
    最近更新 更多