Gui*_*sta 3 sql postgresql recursion common-table-expression
我必须在我的数据库中存储很多项目.每个项目都可以有子项目.结构看起来像一棵树:
Project
/ | \
ProjectChild1 ProjectChild2 [...] ProjectChild[n]
/ |
ProjectChildOfChild1 ProjectChildOfChild2
Run Code Online (Sandbox Code Playgroud)
树的层次是未知的.我正在考虑创建一个这样的表:
表Projects
:
project_ID id_unique PRIMARY_KEY
project_NAME text
project_VALUE numeric
project_PARENT id_unique
Run Code Online (Sandbox Code Playgroud)
在这种情况下,列project_PARENT
将存储父项目的id(如果存在).
对于我的应用程序,我需要检索项目的总值,为此我需要总结每个项目子项和根项目的值.
我知道我需要使用递归,但我不知道如何在Postgres中这样做.
小智 6
像这样的东西:
with recursive project_tree as (
select project_id,
project_name,
project_value,
project_parent
from projects
where project_id = 42 -- << the id of the "base" project
union all
select p.project_id,
p.project_name,
p.project_value,
p.project_parent
from projects p
join project_tree t on t.project_id = p.project_parent
)
select sum(project_value)
from project_tree;
Run Code Online (Sandbox Code Playgroud)
联合的第一部分需要选择您要评估的项目(“子”项目)。递归连接将沿着树向上走并检索所有父项目。
这是@ a_horse 正确答案的简化版本(在评论中与OP讨论后).
适用于递归中任何(合理有限的)级别.
project_id
WITH RECURSIVE cte AS (
SELECT project_id AS project_parent, project_value
FROM projects
WHERE project_id = 1 -- enter id of the base project here !
UNION ALL
SELECT p.project_id, p.project_value
FROM cte
JOIN projects p USING (project_parent)
)
SELECT sum(project_value) AS total_value
FROM cte;
Run Code Online (Sandbox Code Playgroud)
要一次性获得所有项目的总成本:
WITH RECURSIVE cte AS (
SELECT project_id, project_id AS project_parent, project_value
FROM projects
WHERE project_parent IS NULL -- all base projects
UNION ALL
SELECT c.project_id, p.project_id, p.project_value
FROM cte c
JOIN projects p USING (project_parent)
)
SELECT project_id, sum(project_value) AS total_value
FROM cte
GROUP BY 1
ORDER BY 1;
Run Code Online (Sandbox Code Playgroud)
SQL Fiddle(带有正确的测试用例).