使用Postgres的递归树总和?

发布于 01-23 03:19 字数 562 浏览 1 评论 0原文

我有一个看起来像这样的树结构:

                                     root
                       A                               B
              A1           A2                     B1        B2
          A1.1  A1.2      A2.1                   B1.1

桌子看起来像这样:

id | name |value | parent_id
1    root   null    null
2    A      null    1
3    B      null    1    
4    A1     null    2
5    A1.1   2       4
6    A1.2   3       4
.........................

非叶子节点必须包含他们孩子的叶子节点的总和。

我该如何通过快速的Postgres查询来实现此目标

I have a tree structure that looks like this:

                                     root
                       A                               B
              A1           A2                     B1        B2
          A1.1  A1.2      A2.1                   B1.1

the table looks something like this:

id | name |value | parent_id
1    root   null    null
2    A      null    1
3    B      null    1    
4    A1     null    2
5    A1.1   2       4
6    A1.2   3       4
.........................

the non leaf nodes must contain the sum of their children leaf nodes.

how can i achieve this with a fast Postgres query

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

嘿咻 2025-01-30 03:19:58

正如我评论时,如果表中只有一个根节点,则只需使用sum of Value>

SELECT SUM(value)
FROM T

,您可以尝试使用CTE递归来获取要sum

WITH RECURSIVE CTE AS(
 SELECT ID,value,parent_id
 FROM T 
 WHERE value IS NOT NULL
 UNION ALL
 SELECT t1.id,coalesce(t1.value,0) + c.value,t1.parent_id
 FROM CTE c 
 INNER JOIN T t1 ON c.parent_id = t1.id
) 
SELECT id,SUM(value),parent_id
FROM CTE
GROUP BY id,parent_id
order by id

As I comment, If there is only one root node in your table you can just use sum of value

SELECT SUM(value)
FROM T

Or you can try to use CTE RECURSIVE to get which root node you want to SUM

WITH RECURSIVE CTE AS(
 SELECT ID,value,parent_id
 FROM T 
 WHERE value IS NOT NULL
 UNION ALL
 SELECT t1.id,coalesce(t1.value,0) + c.value,t1.parent_id
 FROM CTE c 
 INNER JOIN T t1 ON c.parent_id = t1.id
) 
SELECT id,SUM(value),parent_id
FROM CTE
GROUP BY id,parent_id
order by id

sqlfiddle

纸短情长 2025-01-30 03:19:58

更新24-04-2022

递归cte “ https://www.postgresql.org/docs/current/functions-comparisons.html#id-1.5.8.8.30.16

WITH RECURSIVE r as (
SELECT id
     , name
     , ARRAY[id] as path
     , coalesce(value,0) as value 
  FROM t1
 WHERE name = 'root'
 UNION ALL
SELECT t1.id
     , t1.name
     , array_append(r.path, t1.id) as path
     , r.value + coalesce(t1.value,0) as value
  FROM t1 
 INNER
  JOIN r
    ON t1.parent_id = r.id
)
SELECT id
     , name
     , (select sum(sq.value) from r sq where r.id = any(sq.path) ) as value
  FROM r 

” //www.db-fiddle.com/f/my4cvmmaifkoehsgfczfgv/2“ rel =“ nofollow noreferrer”> db小提琴演示

update 24-04-2022

Solution with recursive CTE, arrays and ANY()

WITH RECURSIVE r as (
SELECT id
     , name
     , ARRAY[id] as path
     , coalesce(value,0) as value 
  FROM t1
 WHERE name = 'root'
 UNION ALL
SELECT t1.id
     , t1.name
     , array_append(r.path, t1.id) as path
     , r.value + coalesce(t1.value,0) as value
  FROM t1 
 INNER
  JOIN r
    ON t1.parent_id = r.id
)
SELECT id
     , name
     , (select sum(sq.value) from r sq where r.id = any(sq.path) ) as value
  FROM r 

DB Fiddle demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文