每个级别的ltree孩子的总和

时间:2015-06-01 09:18:01

标签: sql postgresql ltree

我有一个properties表,其中包含ltree路径和名称列。 Ltree路径包含父节点的id,即" 7968.7969.7987.8000"。每个树节点都有reports,带有一些数值。我需要在ltree中找到每个节点的子节点值的总和。圆括号中的路径

        (1) A 
          |
     __________________________________
     |                |                |
(1.2)B            (1.3)C            (1.4)D
|
|________________________
        |                |
(1.2.5) E         (1.2.6) F

报告

property_id | value
    1       |   1 
    2       |   4
    3       |   19
    4       |   21
    5       |   9
    6       |   11

我需要找到类似

的smth
full_path | subtree_sum
   A      |     60     (1 + 4 + 19 + 21 + 9 + 11)
   A.B    |     24     (4 + 9 + 11)  
   A.C    |     19     (19)
   A.D    |     21     (21)
   A.B.E  |     9      (9)
   A.B.F  |     11     (11)

1 个答案:

答案 0 :(得分:2)

你在这里:

select 
    p.path,
    sum(r.value)
from properties p
left join properties sub on sub.path::text like p.path::text||'%'
left join reports r on r.property_id=sub.id
group by 1; 

它是如何运作的?

对于我们的查询p中调用的每个节点,我们通过加入sub来检索其所有子节点(包括其自身)。要加入我们,请使用like运算符,该运算符允许我们使用p路径作为前缀。应该让您对like运算符(%是通配符)有所了解的快速示例:

select 'prefix1' like 'prefix1%'; --true
select 'prefix1.something' like 'prefix1%'; --true
select 'prefix2' like 'prefix1%'; --false
select 'prefix2.something' like 'prefix1%'; --false

最后一步是将每个子节点的值加起来,加起来并按第一列分组。

修改

我已经自学了一点,找到了更好的解决方案:

select 
    p.path,
    sum(r.value)
from properties p
left join properties sub on sub.path <@ p.path
left join reports r on r.property_id=sub.id
group by 1; 

由于<@运算符使用现有的GiST索引,因此效果更好。