Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 基于汇总类型的树状结构中的总分_Sql Server_Ssms - Fatal编程技术网

Sql server 基于汇总类型的树状结构中的总分

Sql server 基于汇总类型的树状结构中的总分,sql-server,ssms,Sql Server,Ssms,我试图计算树结构中每个节点的总计,计算总计取决于汇总类型 我有如下结构 如果节点类型为当前列表=查看当前节点,则无需在树中向下搜索 如果节点类型为子节点,则忽略当前节点并向下 如果节点类型为“当前”且子节点为“当前”,则包含当前节点 然后下去 假设我的起点是B1:那么总分是=(20+40+110+60+90) 假设我的起点C2:分数是110 我设法把所有的孩子都弄到手了,但到了集合的时候,我被卡住了,请帮帮我 示例数据脚本 +--------+----------+------+-----

我试图计算树结构中每个节点的总计,计算总计取决于汇总类型

我有如下结构

  • 如果节点类型为当前列表=查看当前节点,则无需在树中向下搜索
  • 如果节点类型为子节点,则忽略当前节点并向下
  • 如果节点类型为“当前”且子节点为“当前”,则包含当前节点 然后下去
假设我的起点是B1:那么总分是=(20+40+110+60+90)

假设我的起点C2:分数是110

我设法把所有的孩子都弄到手了,但到了集合的时候,我被卡住了,请帮帮我

示例数据脚本

+--------+----------+------+------------+-------------------+------------------+
| Teamid | ParentId | Name | ParentName |       Type        | Key Result Value |
+--------+----------+------+------------+-------------------+------------------+
|      1 | null     | A1   | Null       | Current and Child |               10 |
|      2 | 1        | B1   | A1         | Current and Child |               20 |
|      3 | 1        | B2   | A1         | Current and Child |               30 |
|      4 | 2        | C1   | B1         | Current List      |               40 |
|      5 | 2        | C2   | B1         | Child List        |               50 |
|      6 | 2        | C3   | B1         | Current and Child |               60 |
|      7 | 4        | D1   | C1         | Current and Child |               70 |
|      8 | 5        | D2   | C2         | Child List        |               80 |
|      9 | 6        | D3   | C3         | Current and Child |               90 |
|     10 | 7        | E1   | D1         | Current List      |              100 |
|     11 | 8        | E2   | D2         | Current and Child |              110 |
+--------+----------+------+------------+-------------------+------------------+
GroupName  GroupSum  GroupSumFormula
---------  --------  ---------------------
A1         360       10+20+30+40+60+90+110
B1         320       20+40+60+90+110
B2         30        30
C1         40        40
C2         110       110
C3         150       60+90
D1         170       100+70
D2         110       110
D3         90        90
E1         100       100
E2         110       110
树表脚本:

CREATE TABLE TreeTable(
   Teamid           INTEGER  NOT NULL PRIMARY KEY 
  ,ParentId         INTEGER 
  ,Name             VARCHAR(2) NOT NULL
  ,ParentName       VARCHAR(4)
  ,Type             VARCHAR(17) NOT NULL
  ,Key_Result_Value INTEGER  NOT NULL
);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (1,NULL,'A1',NULL,'Current and Child',10);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (2,1,'B1','A1','Current and Child',20);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (3,1,'B2','A1','Current and Child',30);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (4,2,'C1','B1','Current List',40);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (5,2,'C2','B1','Child List',50);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (6,2,'C3','B1','Current and Child',60);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (7,4,'D1','C1','Current and Child',70);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (8,5,'D2','C2','Child List',80);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (9,6,'D3','C2','Current and Child',90);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (10,7,'E1','D1','Current List',100);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (11,8,'E2','E2','Current and Child',110);
WITH
CTE_Groups
AS
(
    SELECT
        TreeTable.teamid AS StartID
        ,TreeTable.Name AS StartName
        ,TreeTable.teamid
        ,TreeTable.ParentID
        ,TreeTable.Name
        ,1 AS Lvl
        ,TreeTable.Type
        ,TreeTable.Key_Result_Value
    FROM TreeTable
    
    UNION ALL

    SELECT
        CTE_Groups.StartID
        ,CTE_Groups.StartName
        ,TreeTable.teamid
        ,TreeTable.ParentID
        ,TreeTable.Name
        ,CTE_Groups.Lvl + 1 AS Lvl
        ,TreeTable.Type
        ,TreeTable.Key_Result_Value

    FROM
        TreeTable
        INNER JOIN CTE_Groups ON CTE_Groups.teamid = TreeTable.ParentID
)
select * from CTE_Groups
order by startid,lvl
我的尝试:

CREATE TABLE TreeTable(
   Teamid           INTEGER  NOT NULL PRIMARY KEY 
  ,ParentId         INTEGER 
  ,Name             VARCHAR(2) NOT NULL
  ,ParentName       VARCHAR(4)
  ,Type             VARCHAR(17) NOT NULL
  ,Key_Result_Value INTEGER  NOT NULL
);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (1,NULL,'A1',NULL,'Current and Child',10);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (2,1,'B1','A1','Current and Child',20);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (3,1,'B2','A1','Current and Child',30);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (4,2,'C1','B1','Current List',40);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (5,2,'C2','B1','Child List',50);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (6,2,'C3','B1','Current and Child',60);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (7,4,'D1','C1','Current and Child',70);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (8,5,'D2','C2','Child List',80);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (9,6,'D3','C2','Current and Child',90);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (10,7,'E1','D1','Current List',100);
INSERT INTO TreeTable(Teamid,ParentId,Name,ParentName,Type,Key_Result_Value) VALUES (11,8,'E2','E2','Current and Child',110);
WITH
CTE_Groups
AS
(
    SELECT
        TreeTable.teamid AS StartID
        ,TreeTable.Name AS StartName
        ,TreeTable.teamid
        ,TreeTable.ParentID
        ,TreeTable.Name
        ,1 AS Lvl
        ,TreeTable.Type
        ,TreeTable.Key_Result_Value
    FROM TreeTable
    
    UNION ALL

    SELECT
        CTE_Groups.StartID
        ,CTE_Groups.StartName
        ,TreeTable.teamid
        ,TreeTable.ParentID
        ,TreeTable.Name
        ,CTE_Groups.Lvl + 1 AS Lvl
        ,TreeTable.Type
        ,TreeTable.Key_Result_Value

    FROM
        TreeTable
        INNER JOIN CTE_Groups ON CTE_Groups.teamid = TreeTable.ParentID
)
select * from CTE_Groups
order by startid,lvl
  • 我试图获取节点的所有子节点的屏幕截图,但后来我被困在如何根据类型排除节点上,因为我需要了解完整的路径:

请帮忙 预期结果:

+--------+-----------------------+
| TeamID |         Score         |
+--------+-----------------------+
| E1     | 100                   |
| D1     | 70 + 100              |
| C1     | 40                    |
| E2     | 110                   |
| D2     | 110                   |
| C2     | 110                   |
| D3     | 90                    |
| C3     | 60+90                 |
| B1     | 20+40+110+60+90       |
| B2     | 30                    |
| A1     | 10+30+20+40+110+60+90 |
+--------+-----------------------+

使用递归列出节点子节点是一个良好的开端。使用
case
表达式,您还可以跟踪组类型以及何时添加或忽略值(忽略=使用
0
而不是实际节点值)

解决方案

with rcte as
(
  select t.Name as GroupName,
         t.Type as GroupType,
         t.Name,
         t.Type,
         case t.Type
           when 'Child list' then 0 -- if the current node must be ignored, then the current value changes to 0
           else t.Key_Result_Value
         end as Value
  from TreeTable t
union all
  select r.GroupName,
         r.GroupType,
         t.Name,
         case r.Type
           when 'Current list' then 'Current list' -- if the parent was the end of the sum, then it stays the end of the sum
           else t.Type
         end,
         case
           when r.Type = 'Current list' then 0 -- if the parent was the end of the sum, then the current value changes to 0
           when t.Type = 'Child list' then 0 -- if the current node must be ignored, then the current value changes to 0
           else t.Key_Result_Value
         end
  from rcte r
  join TreeTable t
    on t.ParentName = r.Name
)
select r.GroupName,
       sum(r.Value) as GroupSum,
       string_agg(case when r.Value <> 0 then convert(nvarchar(3), r.Value) end, '+') as GroupSumFormula
from rcte r
group by r.GroupName
order by r.GroupName;

查看实际情况。

您是只想对D1
170
的总数进行汇总,还是需要知道单个总数
70+100
示例数据脚本中存在键入错误。
E2
的父项是
D2
而不是它本身……示例数据脚本中还有另一个输入错误。
D3
的父项是
C3
,而不是
C2
@Charlieface170@Sander我修好了it@sara你的树中有一个循环,在那里抱歉使用了带有打字错误的脚本。它的工作原理就像一个charm@Sander如果情况恰好是多亲,那么当起点为B1时,为什么B1会寻找其父代并获得重复分数?如果B1有多亲,那么这些父代中的每一个都会包含B1的子树值。这样的需求是一个很大的变化,当前的解决方案无法正确处理。请发布一个新问题,其中包含多个家长的数据样本和预期结果。一个新问题会比一个已经回答的问题得到更多的关注。@Sander你能研究一下这个问题吗