自下而上的树结构累加和

问题描述 投票:0回答:1
CREATE TABLE Emissions (
    entityId    VARCHAR(512),
    parentId    VARCHAR(512),
    emission    DECIMAL,
    percentContribution VARCHAR(512)
);

INSERT INTO Emissions (entityId, parentId, emission, percentContribution) VALUES
    ('E1', 'E2', '541', '85'),
    ('E2', 'E4', '272', '85'),
    ('E3', 'E4', '270', '80'),
    ('E4', 'NULL', '362', NULL);

SELECT * FROM Emissions
实体ID 家长ID 排放量 贡献百分比
E1 E2 541 85
E2 E4 272 85
E3 E4 270 80
E4 362

小提琴

我有上面的树结构,我的目标是计算每个节点的累积和,以及子节点的加权贡献。

我首先尝试编写一个自下而上的分层累积和查询,而不首先考虑percentContribution,其中查询将从叶节点向上遍历树:

WITH RECURSIVE C(id, Amount, RootID,tenantid) AS (
    SELECT 
        entityid AS id,
        emissioni AS Amount,
        entityid AS RootID ,
        tenantid
    FROM tree_table
    WHERE entityId NOT IN (
        SELECT DISTINCT parentId FROM tree_table WHERE parentId IS NOT NULL)

    UNION ALL

    SELECT 
        T.parentid AS id,
        C.Amount + T.emission AS Amount,
        C.RootID,
        C.tenantid
    FROM tree_table AS T
    INNER JOIN C ON T.entityid = C.id AND T.tenantid = C.tenantid
)
SELECT 
    T.entityid AS entityid,
    T.parentid,
    T.emission,
    S.AmountIncludingChildren AS total_carbonAmount_marketbased,
    T.name,
    T.category,
    T.scope,
    T.tenantid,
    T.activityid
FROM joined_nuoa_table AS T
INNER JOIN (
             SELECT id, SUM(Amount) AS AmountIncludingChildren
             FROM C
             GROUP BY id
            ) AS S ON T.entityId = S.id
ORDER BY T.entityId

预期结果:

累计_总计
541
541 + 272 = 813
270
362 + 813 + 270 = 1445

实际结果:

累计_总计
541
1082
270
1894

我对自下而上的遍历不太熟悉,所以我不太确定出了什么问题。

考虑百分比贡献后的预期结果

累计_总计
541
272 + (541 * 85 / 100) = 731.85 四舍五入为 732
270
362 + (732 * 85 / 100) + (270 * 85 / 100) = 1213.7 四舍五入到 1214
sql mysql hierarchical-data cumulative-sum
1个回答
0
投票

这是我如何理解您的问题的第一部分(第一个预期结果)以及使用递归 cte 来解决它:

--    S a m p l e    D a t a :
Create Table tree_table 
AS 
  ( Select 'E1' as entityid, 'E2' as parentid, 541 as emission Union All
    Select 'E2', 'E4', 272 Union All
    Select 'E3', 'E4', 270 Union All
    Select 'E4', NULL, 362
  );
WITH     --    R e c u r s i o n :
  Recursive cte (root, entityid, 
                 parentid, entity_emission) AS 
    ( Select     entityid, entityid, 
                 Coalesce(parentid, entityid), 
                 emission
      From       tree_table
      Where      parentid Is Null
     UNION ALL
      Select     cte.root, t.entityid, 
                 t.parentid, 
                 t.emission
      From       cte
      Inner Join tree_table t ON( t.parentid = cte.entityid )
    ) 
--      S Q L :
Select   entityid, parentid, entity_emission, 
         Case When entityid = root 
              Then Sum(entity_emission) Over(Partition By root)
         Else   Case When Coalesce(LAG(parentid) Over(Order By entityid), parentid) = parentid
                     Then entity_emission
                Else Sum(entity_emission) 
                       Over(Partition By root Order By entityid)
                End
         End as cumulative_total
From     cte
Order By entityid
/*        R e s u l t : 
entityid    parentid    entity_emission cumulative_total
---------  ---------    --------------- ----------------
E1         E2                       541              541
E2         E4                       272              813
E3         E4                       270              270
E4         E4                       362             1445    */

问题的第二部分我不清楚。您能否解释一下获得 85% 贡献并选择性地将其应用于 541 和 270 排放背后的逻辑。

© www.soinside.com 2019 - 2024. All rights reserved.