繁体   English   中英

如何使用 sql 获取树中所有父母的孩子的累积总和?

[英]How to get cumulative sum of children for all parents in a tree using sql?

所以我有一个 sql 查询来获取无限深度的树结构,如下所示。 但我对获得每个父母的总数一无所知。

我有一个具有 id、dimensionValueId、名称的表 dimensionValue 我有另一个具有 id、dimensionValue 和 volume 的表评估。 需要在每个父级别添加卷。

I have http://sqlfiddle.com/#!15/5c0e7/5

我还想获得累积总数的平坦 sql,目前我只有树。

WITH RECURSIVE hierarchy AS (
    SELECT
        id,
        name,
        dimensionvalueid,
        0 AS level
    FROM
        dimensionvalue d
    WHERE
        dimensionvalueid IS NULL
    
UNION ALL
SELECT
    e.id,
    e.name,
    e.dimensionvalueid,
    hierarchy.level + 1
FROM
    dimensionvalue e,
    hierarchy
WHERE
    e.dimensionvalueid = hierarchy.id
)
SELECT
    d.id, d.dimensionvalueid, d.name, v.volume
FROM
    hierarchy d
    LEFT JOIN valuation v ON v.dimensionvalueid = d.id
        
    GROUP BY
        d.id,
        d.dimensionvalueid,
        d.name,
        v.volume
    ORDER BY
        d.id;

我已经得到了树,但我想获得从下到上到所有父节点的体积累积总和。 在我的应用程序中,仅添加了较低级别的音量,这些音量加到了父级中。

后来我想嵌套平面数据如下:我想要的output是:

   [
  {
    "id": 1,
    "name": "A1",
    "dimensionValueId": null,
    "sumVolume": 300,
    "children": [
      {
        "id": 2,
        "name": "A1:1",
        "dimensionValueId": 1,
        "sumVolume": 300,
        "children": [
          {
            "id": 3,
            "name": "A1:1:1",
            "dimensionValueId": 2,
            "sumVolume": 300,
            "children": [
              {
                "id": 4,
                "name": "A1:1:1:1",
                "dimensionValueId": 3,
                "sumVolume": 200,
                "children": null
              },
              {
                "id": 5,
                "name": "A1:1:1:2",
                "dimensionValueId": 3,
                "sumVolume": 100,
                "children": null
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "id": 6,
    "name": "B1",
    "dimensionValueId": null,
    "sumVolume": 200,
    "children": [
      {
        "id": 7,
        "name": "B1:1",
        "dimensionValueId": 6,
        "sumVolume": 100,
        "children": null
      },
      {
        "id": 8,
        "name": "B1:2",
        "dimensionValueId": 6,
        "sumVolume": 100,
        "children": [
          {
            "id": 9,
            "name": "B1:2:1",
            "dimensionValueId": 6,
            "sumVolume": 100,
            "children": null
          }
        ]
      }
    ]
  }
]

使用递归cte

with recursive cte(id, h) as (
   select d.id, ('['||d.id||']')::jsonb from dimensionvalue d where d.dimensionvalueid is null
   union all
   select d.id, c.h || ('['||c.id||']')::jsonb from cte c 
   join dimensionvalue d on d.dimensionvalueid = c.id
),
cum_sum(id, s) as (
   select d.id, sum(v1.volume) from dimensionvalue d 
   join cte c on (exists (select 1 from jsonb_array_elements(c.h) v where v.value::int = d.id) 
              and not exists (select 1 from dimensionvalue d1 where d1.dimensionvalueid = c.id)) 
   join valuation v1 on v1.dimensionvalueid = c.id group by d.id
),
tree(id, p, js) as (
   select d.id, d.dimensionvalueid, 'null'::json from dimensionvalue d where not exists (
       select 1 from dimensionvalue d1 where d1.dimensionvalueid = d.id)
   union all
   select d4.id, d4.p, json_agg(d4.js) js from (
       select d.id id, d.dimensionvalueid p, json_build_object('id', t.id, 'name', d3.name, 
            'dimensionValueId', d3.dimensionvalueid, 
            'sumVolume', coalesce(c.s, v1.volume), 'children', t.js) js 
       from dimensionvalue d join tree t on d.id = t.p 
       left join cum_sum c on c.id = t.id join valuation v1 on v1.dimensionvalueid = t.id 
       join dimensionvalue d3 on d3.id = t.id) d4 group by d4.id, d4.p
)
select jsonb_pretty(t3.js::jsonb) from (
   select json_agg(json_build_object('id', t.id, 'name', d3.name, 'dimensionValueId', d3.dimensionvalueid, 'sumVolume', c.s, 'children', t.js)) js 
   from (select t1.id, json_agg(v.value) js 
         from tree t1 cross join json_array_elements(t1.js) v 
         where t1.p is null group by t1.id) t 
   join cum_sum c on c.id = t.id join dimensionvalue d3 on d3.id = t.id) t3

见小提琴

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM