有关sql树型结构统计的问题:

yygyogfny 2009-09-11 11:41:54
现有类似的表结构,其实的score字段是通过统计出来的,实际情况中是不存在这样一个表的。
要求统计出每个节点及这个节点的所有子结点的score值。

我现在用递归函数,对每个结点做一次递归,但效率不行,因为函数要不能访问临时表,我创建了临界的基本表,每次调用此过程的时候用统计出来的信息来填充此表,如果在并发的情况下,这样效率明显不行,
请高手指教。

CREATE TABLE tbTest
(id nvarchar(5),
parentID nvarchar(5),
score decimal(18,2)
)

insert into tbTest
select '1','',10
union all
select '2','1',30
union all
select '3','2',30
union all
select '4','1',50
union all
select '5','',10
union all
select '6','5',30

select * from tbTest

...全文
1160 40 打赏 收藏 转发到动态 举报
写回复
用AI写文章
40 条回复
切换为时间正序
请发表友善的回复…
发表回复
aisunrong 2012-10-30
  • 打赏
  • 举报
回复
好............
locket 2012-08-06
  • 打赏
  • 举报
回复
好...........
hanzhen_hz 2011-03-09
  • 打赏
  • 举报
回复
同意楼上,我也想知道130是怎么算出来的?希望赐教!
闲云的的 2009-09-16
  • 打赏
  • 举报
回复
[Quote=引用 23 楼 yygyogfny 的回复:]
引用 5 楼 happyflystone 的回复:
你要什么结果 ,只要根? 还是任意节点?


id parentid,score
1,'',130(10+30+30+50),
2,'1',60(30+30)
3,'2',30
4,'1',50
5,'',40(10+30)
6,'5',30

我要的结果是这样。
[/Quote]

10+30+30+50 结果不是120吗?130怎么出来的,我纠结了好久。
灰太狼 2009-09-15
  • 打赏
  • 举报
回复
参看:
使用SQL Server 2008中的hierarchyid类型来设计具有树型层次关系的表
http://blog.csdn.net/tjvictor/archive/2009/07/30/4395681.aspx

SQL Server中如何存储具有层次关系的表
http://blog.csdn.net/tjvictor/archive/2009/07/30/4395677.aspx
li_jeck 2009-09-14
  • 打赏
  • 举报
回复
学习
rungoosc 2009-09-14
  • 打赏
  • 举报
回复
再定义一个中间表。记录父子关系,每次统计的时候从中间表中查询所有子节点记录,然后再统计。希望这个思路可以帮到你。

例如:
CREATE TABLE tbTestPath
(id nvarchar(5),
parentID nvarchar(5)
)
-------------------------------------------
构建如下数据:
id parentid
1 1
2 1
3 1
3 2
4 1
5 5
6 5
2 2
3 3
4 4
6 6


select sum(score),parentid from (select tbTest.score ,tbTestPath.*from tbTest inner join tbTestPath on tbTest.id=tbTestPath.id) as a group by a.parentID
skyctr 2009-09-14
  • 打赏
  • 举报
回复
进来学习
liangCK 2009-09-11
  • 打赏
  • 举报
回复
厉害,学习.
soft_wsx 2009-09-11
  • 打赏
  • 举报
回复
CREATE TABLE tbTest --drop table tbtest
(id nvarchar(5),
parentID nvarchar(5),
score decimal(18,2)
)

insert into tbTest
select '01','',10
union all
select '02','01',30
union all
select '03','02',30
union all
select '04','01',50
union all
select '05','',10
union all
select '06','05',30



declare @level_tt table(id nvarchar(1000),parentID nvarchar(1000),level int)
declare @level int
set @level=0
insert @level_tt(id,parentID,level)
select id,id,@level from tbTest where isnull(parentID,'')=''
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tt(id,parentID,level)
select a.id,cast(b.parentID as varchar)+cast(a.id as varchar),@level
from tbTest a,@level_tt b
where a.parentID=b.id and b.level=@level-1
end
select * from @level_tt
select a.id,a.parentID,a.score,SUM(c.score) as 汇总
from tbTest a,@level_tt b,tbTest c,@level_tt d
where a.ID=b.ID and c.ID=d.ID
and d.parentID like b.parentID+'%'
group by a.ID,a.parentID,a.score
order by a.parentID

/*
id parentID score 汇总
01 10.00 120.00
05 10.00 40.00
02 01 30.00 60.00
04 01 50.00 50.00
03 02 30.00 30.00
06 05 30.00 30.00
*/
这样就对了
soft_wsx 2009-09-11
  • 打赏
  • 举报
回复

双编号逐级汇总
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
go
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000),num decimal(14,2))
go
insert tb
select '0001',null,'云南省',100
union all select '0002','0001','昆明市',200
union all select '0003','0001','昭通市',300.3
union all select '0009','0001','大理市',400.4
union all select '0008',null,'四川省',500.5
union all select '0004',null,'贵州省',600.6
union all select '0005','0002','五华区',101.1
union all select '0007','0003','水富县',102.1
union all select '0006','0005','西园路192号',202.1
union all select '0010','0006','金色梧桐3-702',202.2
union all select '0011','0010','昆空科技有限公司',303.1
union all select '0015','0007','两碗乡',303.2
union all select '0013','0015','两碗村',303.4
union all select '0012','0013','某跨国集团董事',444.1
union all select '0014','0008','成都市',111.10






declare @level_tt table(ybh nvarchar(1000),ebh nvarchar(1000),level int)
declare @level int
set @level=0
insert @level_tt(ybh,ebh,level)
select ybh,ybh,@level from tb where ebh is null
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tt(ybh,ebh,level)
select a.ybh,b.ebh+a.ybh,@level
from tb a,@level_tt b
where a.ebh=b.ybh and b.level=@level-1
end
select a.ybh,a.ebh,a.beizhu,a.num,SUM(a.num) as 汇总
from tb a,@level_tt b,tb c,@level_tt d
where a.ybh=b.ybh and c.ybh=d.ybh
and d.ebh like b.ebh+'%'
group by a.ybh,a.ebh,a.beizhu,a.num
order by a.ebh

/*
ybh ebh beizhu num 汇总
0001 NULL 云南省 100.00 1200.00
0004 NULL 贵州省 600.60 600.60
0008 NULL 四川省 500.50 1001.00
0002 0001 昆明市 200.00 1000.00
0003 0001 昭通市 300.30 1501.50
0009 0001 大理市 400.40 400.40
0005 0002 五华区 101.10 404.40
0007 0003 水富县 102.10 408.40
0006 0005 西园路192号 202.10 606.30
0010 0006 金色梧桐3-702 202.20 404.40
0015 0007 两碗乡 303.20 909.60
0014 0008 成都市 111.10 111.10
0011 0010 昆空科技有限公司 303.10 303.10
0012 0013 某跨国集团董事 444.10 444.10
0013 0015 两碗村 303.40 606.80
*/
这样行吗?
htl258_Tony 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 liangck 的回复:]
SQL code;with liangas
(select*,total= scorefrom tbTestas awherenotexists(select*from tbTestwhere a.id= parentid)unionallselect a.*,cast(b.total+ a.scoreasdecimal(18,2))from tbTestas ajoin liangas bon ¡­
[/Quote]
的确不错.
htl258_Tony 2009-09-11
  • 打赏
  • 举报
回复
黄_瓜 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 26 楼 yygyogfny 的回复:]
引用 25 楼 liangck 的回复:
SQL code;with liangas
(select*,total= scorefrom tbTestas awherenotexists(select*from tbTestwhere a.id= parentid)unionallselect a.*,cast(b.total+ a.scoreasdecimal(18,2))from tbTestas ajoin liangas bon ¡­



小梁P,果然厉害,,把统计移到外层,,我咋没有想到呢。。
[/Quote]
yygyogfny 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 25 楼 liangck 的回复:]
SQL code;with liangas
(select*,total= scorefrom tbTestas awherenotexists(select*from tbTestwhere a.id= parentid)unionallselect a.*,cast(b.total+ a.scoreasdecimal(18,2))from tbTestas ajoin liangas bon ¡­
[/Quote]


小梁P,果然厉害,,把统计移到外层,,我咋没有想到呢。。
liangCK 2009-09-11
  • 打赏
  • 举报
回复
;with liang as
(
select *,total = score from tbTest as a
where not exists(select * from tbTest where a.id = parentid)
union all
select a.*,cast(b.total + a.score as decimal(18,2))
from tbTest as a
join liang as b
on a.id = b.parentid
)
select a.id,a.parentid,isnull(b.score,a.score) as score
from tbTest as a
left join (select id,parentid,sum(total) as score
from liang group by id,parentid) as b
on a.id=b.id and a.parentid=b.parentid
黄_瓜 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 yygyogfny 的回复:]
id parentid,score
1,'',130(10+30+30+50),
2,'1',60(30+30)
3,'2',30
4,'1',50
5,'',40(10+30)
6,'5',30

我要的结果是这样。
[/Quote]

这个找石头哥帮你搞定。
yygyogfny 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 happyflystone 的回复:]
你要什么结果 ,只要根? 还是任意节点?
[/Quote]

id parentid,score
1,'',130(10+30+30+50),
2,'1',60(30+30)
3,'2',30
4,'1',50
5,'',40(10+30)
6,'5',30

我要的结果是这样。
yygyogfny 2009-09-11
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 fredrickhu 的回复:]
呵呵 我不是很会 SORRY
[/Quote]

别这样咯~~
--小F-- 2009-09-11
  • 打赏
  • 举报
回复
呵呵 我不是很会 SORRY
加载更多回复(20)

22,210

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server 疑难问题
社区管理员
  • 疑难问题社区
  • 尘觉
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧