Postgre / SQL 递归查询

Postgre / SQL queries with recursive

我正在尝试创建某个 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   |

我需要的是 return 一门课程的 CNr 及其本身的成本加上所有前期课程的总和。使用给定的表格,它应该如下所示:

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

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

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

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

您可以使用递归 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.