问题描述
我正在尝试使用CTE进行递归求和,但我需要的值必须从另一个表中汇总。
将孩子的总和相加并添加到父节点的值中,而我的问题是递归部分不允许分组和聚合。对于这种情况,可能还有另一种方法。
我的数据:
主表(tEvent
)
Id ParentId Name
-------------------------------------------------------
1 Main Project
2 1 Sub Project
3 2 Task 1.1
4 2 Task 1.2
5 1 Task 2
6 1 Task 3
附加表(tBooking
)
Id EventId Value
------------------------------------------------
1 1 4
2 2 5
3 2 10
4 3 8
5 4 5
6 4 15
7 5 18
8 6 40
9 6 12
10 6 9
预期结果
Id Name SummedUp
---------------------------------------------------
1 Main Project 126
2 Sub Project 43
3 Task 1.1 8
4 Task 1.2 20
5 Task 2 18
6 Task 3 61
架构设置:
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE [TABLE_NAME] = 'tEvent')
BEGIN
DROP TABLE [tEvent]
END
CREATE TABLE [dbo].[tEvent]
(
[Id] NVARCHAR (50) NOT NULL,[Name] NVARCHAR (50) NOT NULL,[ParentId] NVARCHAR (50) NOT NULL
);
INSERT INTO tEvent(Id,ParentId,Name) VALUES ('1','','Main Project');
INSERT INTO tEvent(Id,Name) VALUES ('2','1','Sub Project');
INSERT INTO tEvent(Id,Name) VALUES ('3','2','Task 1.1');
INSERT INTO tEvent(Id,Name) VALUES ('4','Task 1.2');
INSERT INTO tEvent(Id,Name) VALUES ('5','Task 2');
INSERT INTO tEvent(Id,Name) VALUES ('6','Task 3');
IF EXISTS (SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE [TABLE_NAME] = 'tBooking')
BEGIN
DROP TABLE [tBooking]
END
CREATE TABLE [dbo].[tBooking]
(
[Id] NVARCHAR (50) NOT NULL,[EventId] NVARCHAR (50) NOT NULL,[Value] [FLOAT]
);
INSERT INTO tBooking(Id,EventId,Value) VALUES ('1','4');
INSERT INTO tBooking(Id,Value) VALUES ('2','5');
INSERT INTO tBooking(Id,Value) VALUES ('3','10');
INSERT INTO tBooking(Id,Value) VALUES ('4','3','8');
INSERT INTO tBooking(Id,Value) VALUES ('5','4',Value) VALUES ('6','15');
INSERT INTO tBooking(Id,Value) VALUES ('7','5','18');
INSERT INTO tBooking(Id,Value) VALUES ('8','6','40');
INSERT INTO tBooking(Id,Value) VALUES ('9','12');
INSERT INTO tBooking(Id,Value) VALUES ('10','9');
我的查询:
;WITH CTE AS
(
SELECT
A.Id,SUM(B.Value) Value,A.Id Root
FROM tEvent A
LEFT JOIN tBooking B
ON A.Id = B.EventId
GROUP BY A.Id
UNION ALL
SELECT
A.Id,B.Value,CTE.Id
FROM tEvent A
INNER JOIN CTE
ON A.ParentId = CTE.Id
INNER JOIN tBooking B
ON A.Id = B.EventId
)
SELECT * FROM CTE;
这里是sqlfiddle。
非常感谢您的帮助。
解决方法
您可以总结如下。 因此,在您的小提琴中,我看到name和parentid列可能已被颠倒。以下查询基于您的小提琴。 这里也链接到您的modified fiddle
; with bookingtotal as
(
select
Eventid,value = sum(value)
from tBooking
group by EventId
),recursiontree as
(
select
ParentId=id,eventid=id
from tEvent
union all
select
id=case when T.ParentId<>'' then T.ParentId else t.id end,eventId=e.eventid
from recursiontree e
join tEvent t on e.ParentId=t.Id
where T.ParentId<>''
),eventTotal as
(select ParentId,sum(value) as value
from recursiontree e
join bookingtotal b on e.eventId=b.Eventid
group by ParentId
)
select e.*,value from eventTotal t join tEvent e
on e.id=t.ParentId