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