小弟现在在做一个程序,由于叶子节点有重量,上级节点的值又是其下级节点值的和,不知如何实现。
例如:
上级节点 下级节点 重量
A B
A C
B D
B E 5
C F 17
D G 10
如何通过叶子节点E、F、G的重量求出上级节点A、B、C、D的重量
例如:
上级节点 下级节点 重量
A B
A C
B D
B E 5
C F 17
D G 10
如何通过叶子节点E、F、G的重量求出上级节点A、B、C、D的重量
select * from table where 下级节点 in(select 上级节点 from talbe)
这样查出来再用sum汇总,
代码手写没有测试过
顺便问一下CTE的全称是什么,CTE是不是就是讲WITH AS的
---测试数据
create table tree(parentsnode varchar(20),childnode varchar(20),weight int)
insert into tree
select 'a','b',null
union
select 'b','c',null
union
select 'b','d', 6
union
select 'b','e', 5----创建存储过程 ,参数为目标节点
alter proc P_TREE
@node varchar(20)
as
begin
declare @level int=1
declare @TREE table (parentsnode varchar(20),childnode varchar(20),[weight] int,[level] int)
while @level>=1
begin
if @level=1
insert into @TREE(parentsnode,childnode,[weight],[level])
select parentsnode,childnode,[weight],@level
from TREE
where parentsnode=@node or childnode=@node --非叶节点或叶节点
else
insert into @TREE(parentsnode,childnode,[weight],[level])
select parentsnode,childnode,[weight],@level
from TREE
where parentsnode in (select childnode from @TREE where [level]=@level-1)
if @@ROWCOUNT>0
set @level=@level+1
else
set @level=-1 -- 已经加载完全部叶子,准备退出循环
end
select sum(isnull([weight],0)) as 重量 from @TREE
end
create proc P_TREE
DROP TABLE test
go
CREATE TABLE test (上级节点 VARCHAR(10), 下级节点 VARCHAR(10), 重量 INT )
GO
INSERT INTO test
SELECT 'A','B',NULL
UNION ALL
SELECT 'A','C',NULL
UNION ALL
SELECT 'B','D',NULL
UNION ALL
SELECT 'B','E',5
UNION ALL
SELECT 'C','F',17
UNION ALL
SELECT 'D','G',10
;WITH cte
AS
(
--先找出叶子节点
SELECT 上级节点 , 下级节点 , 重量
FROM test
WHERE 重量 IS NOT NULL
UNION ALL
--找出叶子节点的上级节点及上级节点的上级节点,以此类推
SELECT b.上级节点,b.下级节点,a.重量
FROM cte a INNER JOIN test b ON a.上级节点=b.下级节点
)
SELECT 上级节点 节点, SUM(重量) 重量 FROM cte GROUP BY 上级节点
/*
节点 重量
---------- -----------
A 32
B 15
C 17
D 10
(4 行受影响)
*/