【发布时间】:2021-11-01 18:39:40
【问题描述】:
这是条目的层次结构。
_________Milky Way (30)________
/ | \
Alpha(10) Beta(20) Delta(null)
/ \ |
Mars(7) Jupiter(3) Delta-child(44)
父值是子值的总和。 例如。
Alpha = Mars + Jupiter = 7 + 3 = 10
Milky Way = Alpha + Beta + Delta = 10 + 20 + null = 30
任务:重新计算父级直到根,以防任何子级更新。让我们甚至简化 任务:选择所有条目,直到根,并重新计算值。
假设 Mars 已更新。现在 Mars 的值为 2。
_________Milky Way (?)________
/ | \
Alpha(?) Beta(20) Delta(null)
/ \ |
Mars(2) Jupiter(3) Delta-child(44)
这意味着所有的父母都应该更新:
Alpha = Mars + Jupiter = 2 + 3 = 5
Milky Way = Alpha + Beta + Delta = 5 + 20 + null = 25.
注意: Delta -> Delta-child 耦合已损坏,一切正常。它可能发生,让我们把它放在这里的范围之外。 '添加此示例只是为了确保在计算过程中不会对其进行计数,因为层次结构可能足够大,并且没有任务重新计算所有子叶子,只需要从父节点到根节点。
由于一些“从层次结构中选择..”
我想收到重新计算的父母的价值观。
前任。
| id | name | value |
|---|---|---|
| 1 | Milky Way | 25 |
| 2 | Alpha | 5 |
已更新 Mars 的代码示例(sqlfiddle 链接如下):
Schema
CREATE TABLE hierarchy
(
id int4,
parent_id int4,
name varchar(255),
value int4
);
价值观
insert into hierarchy
values
(1, null, 'Milky Way', 30),
(2, 1, 'Alpha', 10),
(3, 1, 'Beta', 20),
(4, 1, 'Delta', null),
(5, 2, 'Mars', 2),
(6, 2, 'Jupiter', 3),
(7, 4, 'Delta-child', 44);
我的尝试:
-
我能够列出所有应该在计算中使用的叶子
sqlfiddle 1WITH RECURSIVE cte AS ( SELECT h1.id, h1.parent_id, h1.name , h1.value from hierarchy h1 where h1.id = 5 UNION SELECT h2.id, h2.parent_id, h2.name , h2.value from hierarchy h2 JOIN cte cte ON (cte.parent_id = h2.parent_id or cte.parent_id = h2.id ) where cte.id != h2.id ) select * from cte order by id -
当我尝试对值求和时,由于某种原因,查询进入无限循环
sqlfiddle 2WITH RECURSIVE cte AS ( SELECT h1.id, h1.parent_id, h1.name , h1.value from hierarchy h1 where h1.id = 5 UNION SELECT h2.id, h2.parent_id, h2.name , (h2.value + cte.value) as value from hierarchy h2 JOIN cte cte ON (cte.parent_id = h2.parent_id or cte.parent_id = h2.id ) where cte.id != h2.id ) select * from cte order by id -
我尝试了另外一个查询,不幸的是它不包括父母的兄弟姐妹。
sqlfiddle 3WITH RECURSIVE cte AS ( SELECT h1.id, h1.parent_id, h1.name , h1.value from hierarchy h1 where h1.parent_id = (select parent_id from hierarchy where id = 5) UNION SELECT h2.id, h2.parent_id, h2.name , cte.value as value from hierarchy h2 JOIN cte cte ON (cte.parent_id = h2.parent_id or cte.parent_id = h2.id ) where cte.id != h2.id ) select id, parent_id, name, sum(value) from cte group by id, parent_id, name order by id
如有任何帮助,我将不胜感激。 :-)
【问题讨论】:
标签: sql postgresql recursive-query