我正在处理以前没有遇到过的数据结构。该表是树层次结构,看起来像这样:
CREATE TABLE Tree (
TreeID INT, -- Primary key id
TreeLevel INT, -- Level in the tree
TreeDown INT, -- TreeID of first node at the next lower level
TreeRight INT -- TreeID of the next node at the same level with 0 being the end
)
然后,我有一个项目列表,这些项目通过TreeID链接到层次结构中的各个节点。 E.g:
CREATE TABLE Items (
ItemID INT,
TreeID INT, -- Node in the tree hierarchy
Value INT
)
我想在树的顶层做一个选择和分组,所以包括所有的孩子。例如:
SELECT Tree.TreeID, SUM(Items.Value) FROM Items
JOIN Tree ON Tree.TreeID = Items.TreeID AND Tree.TreeLevel = 0
GROUP BY Tree.TreeID
当然,这实际上并不起作用,只是以此为例。实际上,这只包括显式分配给碰巧具有0级但不是其子级的树节点的项。我如何包括他们的孩子?
如果重要的话,我正在使用SQL Server 2008,但是不可知的解决方案会很棒。
答案 0 :(得分:1)
看看这个相关的问题。你需要创建一个recursive-cte,这有类似的问题/解决方案。
答案 1 :(得分:0)
TreeLevel 对于解决方案来说是不必要的,所以我将其排除在外。
create table Tree
(
TreeID int -- Primary key id
,TreeDown int -- TreeID of first node at the next lower level
,TreeRight int -- TreeID of the next node at the same level with 0 being the end
)
;
insert into Tree (TreeID,TreeDown,TreeRight) values (1,2,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (2,4,3);
insert into Tree (TreeID,TreeDown,TreeRight) values (3,7,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (4,0,5);
insert into Tree (TreeID,TreeDown,TreeRight) values (5,0,6);
insert into Tree (TreeID,TreeDown,TreeRight) values (6,0,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (7,8,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (8,0,9);
insert into Tree (TreeID,TreeDown,TreeRight) values (9,0,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (10,11,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (11,0,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (12,13,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (13,0,14);
insert into Tree (TreeID,TreeDown,TreeRight) values (14,15,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (15,16,0);
insert into Tree (TreeID,TreeDown,TreeRight) values (16,0,0);
create table Items
(
ItemID int
,TreeID int -- Node in the tree hierarchy
,Val int
)
;
insert into Items (ItemID,TreeID,Val) values (1001,1,1);
insert into Items (ItemID,TreeID,Val) values (1002,1,1);
insert into Items (ItemID,TreeID,Val) values (1004,6,2);
insert into Items (ItemID,TreeID,Val) values (1005,7,2);
insert into Items (ItemID,TreeID,Val) values (1006,8,0);
insert into Items (ItemID,TreeID,Val) values (1007,9,3);
insert into Items (ItemID,TreeID,Val) values (1008,12,4);
insert into Items (ItemID,TreeID,Val) values (1009,15,3);
insert into Items (ItemID,TreeID,Val) values (1010,15,2);
insert into Items (ItemID,TreeID,Val) values (1011,15,1);
with cte (root_TreeId,TreeId,TreeDown,TreeRight)
as
(
select t.TreeId as root_TreeId
,t.TreeId
,t.TreeDown
,t.TreeRight
from Tree t
where t.TreeId not in (select TreeDown from Tree union select TreeRight from Tree)
union all
select c.root_TreeId
,t.TreeID
,t.TreeDown
,t.TreeRight
from cte c
join Tree t
on t.TreeID = c.TreeDown
or t.TreeID = c.TreeRight
)
select c.root_TreeID
,count (distinct c.TreeID) as nodes
,count (i.ItemID) as items
,sum (i.Val) as sum_item_value
from cte c
left join Items i
on i.TreeID =
c.TreeID
group by c.root_TreeID
;