关于树形结构的分级汇总的SQL优化算法。

有一张表示树形的表:
ID Name Amount ParentID
1 00001 ? Null
2 00001-00001 60000 1
3 00001-00002 40000 1
4 00002 10000 Null
5 00003 ? Null
6 00003-00001 ? 5
7 00003-00001-00001 1000 6
8 00003-00002 100 5
9 00003-00003 10 5
10 00004 ? Null
11 00004-00001 1 10
12 00004-00002 ? 10
13 00004-00002-00001 0.1 12
14 00004-00002-00002 0.01 12
15 00004-00002-00003 0.001 12
已知叶级的Amount值,现在需要根据Name的层次(1个"-"表示1层),依此向上,求Amount的汇总值,即应得出如下的结果:
ID Name Amount ParentID
1 00001 100000 Null
2 00001-00001 60000 1
3 00001-00002 40000 1
4 00002 10000 Null
5 00003 1110 Null
6 00003-00001 1000 5
7 00003-00001-00001 1000 6
8 00003-00002 100 5
9 00003-00003 10 5
10 00004 1.111 Null
11 00004-00001 1 10
12 00004-00002 0.111 10
13 00004-00002-00001 0.1 12
14 00004-00002-00002 0.01 12
15 00004-00002-00003 0.001 12

假设Name中的层数是不定的,表中的记录数超过1万条。
在SQL Server数据库中,用怎样的算法,计算最快?这个算法是要用到数据库端的,增加字段、增加表、临时表、触发器等手段均可,但是要考虑性能,欢迎大家讨论!
---------------------------------------------------------------

不过我建议你在表里加几个字段:
fhaschild--是否有子节点
flevel--是第几层
这样在做类似统计时对效率有很大的好处。只是在新增修改时算法会麻烦一点。
如果有这两个字段,上面的语句会简化些,且效率高很多。
---------------------------------------------------------------

我试了一下:
create table t3 (ID int,Name varchar(20),Amount decimal(10,4),ParentID int)
insert t3 select 1, '00001', null, Null
union all select 12, '00004-00002' ,null, 10
union all select 13, '00004-00002-00001' ,0.1, 12
union all select 2, '00001-00001' ,60000, 1
union all select 7, '00003-00001-00001' ,1000, 6
union all select 8, '00003-00002' ,100, 5
union all select 9, '00003-00003' ,10, 5
union all select 10, '00004' ,null, Null
union all select 11, '00004-00001' ,1, 10
union all select 14, '00004-00002-00002' ,0.01, 12
union all select 15, '00004-00002-00003' ,0.001, 12
union all select 3, '00001-00002' ,40000, 1
union all select 4, '00002' ,10000, Null
union all select 5, '00003' ,null, Null
union all select 6, '00003-00001' ,null, 5
--上面打乱了

update a set amount=0 from t3 a where exists(select 1 from t3 where ParentID=a.id)
--影响5行
update a set amount=(select sum(amount) from t3 where left(name,len(a.name)+1)=a.name+'-') from t3 a where exists(select 1 from t3 where ParentID=a.id)
--影响5行
select * from t3 order by id

ID Name Amount ParentID
----------- -------------------- ------------ -----------
1 00001 100000.0000 NULL
2 00001-00001 60000.0000 1
3 00001-00002 40000.0000 1
4 00002 10000.0000 NULL
5 00003 1110.0000 NULL
6 00003-00001 1000.0000 5
7 00003-00001-00001 1000.0000 6
8 00003-00002 100.0000 5
9 00003-00003 10.0000 5
10 00004 1.1110 NULL
11 00004-00001 1.0000 10
12 00004-00002 .1110 10
13 00004-00002-00001 .1000 12
14 00004-00002-00002 .0100 12
15 00004-00002-00003 .0010 12

(所影响的行数为 15 行)

没有错啊?
---------------------------------------------------------------

不清零会造成重复计算
触发器是在插入或者修改时计算,不必集中统计。
表中只有ID、Amount、ParentID,可以先把字节点id放到临时表,再update
怎么给分自己作主,不必看人家意见。

Published At
Categories with 数据库类
Tagged with
comments powered by Disqus