我必须在我的数据库中存储很多项目。每个项目都可以有子项目。结构看起来像一棵树:
Project
/ | \
ProjectChild1 ProjectChild2 [...] ProjectChild[n]
/ |
ProjectChildOfChild1 ProjectChildOfChild2
树的等级是未知的。 我想创建一个这样的表:
表Projects
:
project_ID id_unique PRIMARY_KEY
project_NAME text
project_VALUE numeric
project_PARENT id_unique
在这种情况下,列project_PARENT
将存储父项目的ID(如果存在)。
对于我的应用程序,我需要检索项目的总值,为此我需要将每个项目子项和根项目的值相加。
我知道我需要使用递归,但我不知道如何在Postgres中这样做。
答案 0 :(得分:5)
这是@a_horse's correct answer的简化版本(在评论中与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;
一次性获得所有项目的总费用:
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;
SQL Fiddle(有正确的测试用例)。
答案 1 :(得分:3)
这样的事情:
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;
联盟的第一部分需要选择您要评估的项目(“子”项目)。递归连接将向上走树并检索所有父项目。