[英]SQL Server - How to add column with group subtotals to the query results
我有一个数据库表,其中有放置在树层次结构中的项目。 项目具有其ID和ParentID。 每个项目都有一个分配的金额,因此,当我在层次结构及其金额中提取数据时,它看起来像这样:
| ID | Name | ParentID | Level | Amount |
| 1 | ITEM 1 | NULL | 0 | 100 |
| 3 | - Item 1-1 | 1 | 1 | 100 |
| 7 | - - Item 1-1-1 | 3 | 2 | 100 |
| 8 | - - Item 1-1-2 | 3 | 2 | 100 |
| 4 | - Item 1-2 | 1 | 1 | 100 |
| 9 | - - Item 1-2-1 | 4 | 2 | 100 |
| 10 | - - Item 1-2-2 | 4 | 2 | 100 |
| 2 | ITEM 2 | NULL | 0 | 200 |
| 5 | - Item 2-1 | 2 | 1 | 200 |
| 11 | - - Item 2-1-1 | 5 | 2 | 200 |
| 12 | - - Item 2-1-2 | 5 | 2 | 200 |
| 6 | - Item 2-2 | 2 | 1 | 200 |
| 13 | - - Item 2-2-1 | 6 | 2 | 200 |
| 14 | - - Item 2-2-2 | 6 | 2 | 200 |
假设这是一个新表。 我需要从中选择数据,还需要为每个层次结构级别按金额计算组小计:
| ID | Name | ParentID | Level | Amount | Group rollup |
| 1 | ITEM 1 | NULL | 0 | 100 | 700 |
| 3 | - Item 1-1 | 1 | 1 | 100 | 300 |
| 7 | - - Item 1-1-1 | 3 | 2 | 100 | 100 |
| 8 | - - Item 1-1-2 | 3 | 2 | 100 | 100 |
| 4 | - Item 1-2 | 1 | 1 | 100 | 300 |
| 9 | - - Item 1-2-1 | 4 | 2 | 100 | 100 |
| 10 | - - Item 1-2-2 | 4 | 2 | 100 | 100 |
| 2 | ITEM 2 | NULL | 0 | 200 | 1400 |
| 5 | - Item 2-1 | 2 | 1 | 200 | 600 |
| 11 | - - Item 2-1-1 | 5 | 2 | 200 | 200 |
| 12 | - - Item 2-1-2 | 5 | 2 | 200 | 200 |
| 6 | - Item 2-2 | 2 | 1 | 200 | 600 |
| 13 | - - Item 2-2-1 | 6 | 2 | 200 | 200 |
| 14 | - - Item 2-2-2 | 6 | 2 | 200 | 200 |
请帮我实现这个目标。
现在,我正在使用此查询来选择数据。 但是,它无法正确订购商品,也不会进行汇总。 您是否可以按以上所示调整它们的顺序并计算组汇总?
WITH cte AS
(SELECT ID,
Name,
ParentID,
0 AS LEVEL,
Amount
FROM MyTable
WHERE ParentID IS NULL
UNION ALL
SELECT t.ID,
t.Name,
t.ParentID,
LEVEL+1,
t.Amount
FROM cte
JOIN MyTable t ON cte.ID = t.ParentID)
SELECT d1.*
FROM cte d1
将整个表(所有层次结构)的TOTAL汇总放在单独的行中会很好。
现有的结果数据使我认为您可能已经在使用某种形式的递归CTE来构建Level
和Name
类的东西。 如果是这样,则可能可以同时计算hier
。
但是,如果没有,我们使用递归CTE来建立我们的hier
列,然后使用IsDescendantOf
计算的款项时:
declare @t table(ID int, Name varchar(30), ParentID int, Level int, Amount int)
insert into @t(ID ,Name , ParentID , Level , Amount) values
(1 ,'ITEM 1 ',NULL, 0 ,100 ),
(3 ,' - Item 1-1 ', 1, 1 ,100 ),
(7 ,' - - Item 1-1-1', 3, 2 ,100 ),
(8 ,' - - Item 1-1-2', 3, 2 ,100 ),
(4 ,' - Item 1-2 ', 1, 1 ,100 ),
(9 ,' - - Item 1-2-1', 4, 2 ,100 ),
(10 ,' - - Item 1-2-2', 4, 2 ,100 ),
(2 ,'ITEM 2 ',NULL, 0 ,200 ),
(5 ,' - Item 2-1 ', 2, 1 ,200 ),
(11 ,' - - Item 2-1-1', 5, 2 ,200 ),
(12 ,' - - Item 2-1-2', 5, 2 ,200 ),
(6 ,' - Item 2-2 ', 2, 1 ,200 ),
(13 ,' - - Item 2-2-1', 6, 2 ,200 ),
(14 ,' - - Item 2-2-2', 6, 2 ,200 )
;With hierarchy as (
select ID, Name, '/' + CONVERT(varchar(max),ID) + '/' as hier,Amount
from @t
where ParentID is null
union all
select t.ID,t.Name, hier + CONVERT(varchar(max),t.ID) + '/',t.Amount
from
hierarchy h
inner join
@t t
on
t.ParentID = h.ID
), Typed as (
select ID,Name,Amount,CONVERT(hierarchyid,hier) as hier
from hierarchy
)
select
*
from
Typed t1
cross apply
(select SUM(Amount) as GroupTotal from Typed t2
where t2.hier.IsDescendantOf(t1.hier) = 1) u
order by hier
结果:
ID Name Amount hier GroupTotal
----------- ------------------------------ ----------- ------------- -----------
1 ITEM 1 100 0x58 700
3 - Item 1-1 100 0x5BC0 300
7 - - Item 1-1-1 100 0x5BE7 100
8 - - Item 1-1-2 100 0x5BE880 100
4 - Item 1-2 100 0x5C20 300
9 - - Item 1-2-1 100 0x5C34C0 100
10 - - Item 1-2-2 100 0x5C3540 100
2 ITEM 2 200 0x68 1400
5 - Item 2-1 200 0x6C60 600
11 - - Item 2-1-1 200 0x6C75C0 200
12 - - Item 2-1-2 200 0x6C7640 200
6 - Item 2-2 200 0x6CA0 600
13 - - Item 2-2-1 200 0x6CB6C0 200
14 - - Item 2-2-2 200 0x6CB740 200
您也可以在此阶段决定需要更改数据模型,以便直接使用hierarchyid
类型而不是Parent / Child来对hierarchyid
建模。 这取决于此数据必须满足的其他用例。
这里的问题是,大多数层次查询最终倾向于自上而下地探索层次结构,但是所需的数据只能自下而上地获得。 我确实尝试确定是否有一个聪明的GROUP BY
或ORDER BY
表达式(后者用于窗口函数)也可以使用IsDescendantOf
但失败了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.