如何使用其值对多个节点权重进行计算,然后使用sql server 2008计算父子层次结构中所有子节点的总和

时间:2017-11-20 21:35:25

标签: sql asp.net sql-server sql-server-2008 tsql

我有一个场景,我必须通过将节点值与节点权重相乘来找到每个子节点的百分比(例如NodeVal *(NodeWeight / 100)),然后对所有子节点的这些计算值求和并将其添加到它的父级,现在在这个新计算的父级的一个级别上也有它的权重,它将与其值相乘,然后我们将计算该级别的所有子节点的总和并将其添加到其上一级的父级,依此类推

如果我们只是计算所有子节点的总和,那么在互联网上找到的查询工作正常,但在我的情况下没有帮助。

我正在使用以下查询,但它不会返回准确的结果。

    CREATE TABLE TEMP(
      Id INT
      ,ParentNodeId INT
      ,Weight FLOAT
      ,Score FLOAT    
      );

      INSERT INTO TEMP
            VALUES (2, 1, 0, 0),
            (3, 2, 100, 0),
            (4, 2, 100, 0),
            (5, 2, 100, 0),
            (6, 3, 40, 100),
            (7, 3, 30, 0),
            (8, 3, 30, 100),
            (9, 7, 10, 100),
            (10, 7, 40, 100),
            (11, 7, 50, 0),
            (12, 11, 30, 100),
            (13, 11, 70, 0),
            (14, 13, 50, 100),
            (15, 13, 50, 100);


WITH cte(Id, ParentNodeId, LEVEL, Struc, Weight, Score)
            AS
            (
            SELECT t.Id, t.ParentNodeId, 0 AS LEVEL, CAST(':' + CAST(t.Id AS VARCHAR) + ':' AS VARCHAR(MAX)) AS Struc, t.Weight, t.Score 
            FROM TEMP t
            WHERE t.ParentNodeId = 2 
            UNION ALL
            SELECT t.Id, t.ParentNodeId, LEVEL + 1 AS LEVEL, CAST(e.Struc + CAST(t.Id AS VARCHAR) + ':' AS VARCHAR(MAX)) AS Struc, t.Weight, t.Score 
            FROM TEMP t
            INNER JOIN cte e ON e.Id = t.ParentNodeId           
            )

select c1.Id, c1.ParentnodeId, c1.weight, c1.score,c1.struc,
SUM(c2.score  * (c2.weight/100 )) ProductCountIncludingChildren
from cte c1
left outer join cte c2 on c1.struc <> c2.struc and left(c2.struc, LEN(c1.struc)) = c1.struc
group by c1.Id, c1.ParentnodeId, c1.weight, c1.score, c1.struc
order by c1.Id

此查询仅适用于离开节点,但不适用于上述级别。 SQL Fiddle Link

请让我知道,如何解决这个问题。提前感谢您的帮助 - :)

2 个答案:

答案 0 :(得分:0)

我无法编辑我的问题,因此我将所需的输出添加为答案:

Id  P_Id    weight  score   ChildSum
3   2        100    0   100
4   2        100    0   (null)
5   2        100    0   (null)
6   3        40     100 (null)
7   3        30     0   100
8   3        30     100 (null)
9   7        10     100 (null)
10  7        40     100 (null)
11  7        50     0   100
12  11       30     100 (null)
13  11       70     0   100
14  13       50     100 (null)
15  13       50     100 (null)

这样的计算总和:Id13的childSum将是([id 14的分数] *([id 14的重量] / 100))加([id 15的分数] *([id 15的重量] / 100)) =&GT;&GT;&GT; (100 *(50/100))+(100 *(50/100))=&gt; 100

等等。

答案 1 :(得分:0)

您可以使用CTE,但我选择使用左连接。

            Select  ID as ID,
                    ParentNodeId as P_ID,
                    Weight as Weight,
                    Score as Score,
                    isnull(Sums,0) as ChildSum
            From #TEMP
            Left Join ( Select  ParentNodeId as P_ID, 
                                isnull(Sum(Score*(Weight/100.0)),0) as Sums 
                        from #TEMP 
                        group by ParentNodeId
                        ) as ParSum on P_ID=ID

希望你在寻找什么