要求统计出每个节点及这个节点的所有子结点的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
40 个解决方案
#1
sf
#2
咋一看,原来是火鸟大侠
#3
db
#4
小虾是来诚心请教各位的~~多多指教。
#5
你要什么结果 ,只要根? 还是任意节点?
#6
/*看下下
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 Copyright (c)
1988-2008 Microsoft Corporation Enterprise Evaluation Edition on Windows NT 5.1 <X86>
(Build 2600: Service Pack 3)
愿和大家共同进步
如有雷同、实属巧合
●●●●●2009-09-03 17:47:36.077●●●●●
★★★★★soft_wsx★★★★★
*/
--树型结构处理之双编号(广度深度排序)
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000))
insert tb
select '0001',null,'云南省'
union all select '0002','0001','昆明市'
union all select '0003','0001','昭通市'
union all select '0009','0001','大理市'
union all select '0008',null,'四川省'
union all select '0004',null,'贵州省'
union all select '0005','0002','五华区'
union all select '0007','0002','水富县'
union all select '0006','0005','西园路192号'
union all select '0010','0006','金色梧桐'
union all select '0011','0010','科技有限公司'
union all select '0015','0007','两碗乡'
union all select '0013','0015','两碗村'
union all select '0012','0013','某跨国集团董事长'
union all select '0014','0008','成都市'
--select * from tb
--广度排序(先显示第一层节点,再显示第二次节点......)
--定义辅助表
declare @level_tb table(bh nvarchar(10),level int)
declare @level int
set @level=0
insert @level_tb(bh,level)
select ybh,@level from tb where ebh is null
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tb(bh,level)
select ybh,@level
from tb a,@level_tb b
where a.ebh=b.bh
and b.level=@level-1
end
select a.*,b.* from tb a,@level_tb b where a.ybh=b.bh order by level
/*
ybh ebh beizhu bh level
0001 NULL 云南省 0001 0
0008 NULL 四川省 0008 0
0004 NULL 贵州省 0004 0
0002 0001 昆明市 0002 1
0003 0001 昭通市 0003 1
0009 0001 大理市 0009 1
0014 0008 成都市 0014 1
0005 0002 五华区 0005 2
0007 0002 水富县 0007 2
0006 0005 西园路192号 0006 3
0015 0007 两碗乡 0015 3
0010 0006 金色梧桐 0010 4
0013 0015 两碗村 0013 4
0011 0010 科技有限公司 0011 5
0012 0013 某跨国集团董事长 0012 5
*/
--深度排序(模拟单编码法)
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*(无列名) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0001 0
----昆明市 0002 0001 昆明市 0002 00010002 1
----五华区 0005 0002 五华区 0005 000100020005 2
----西园路192号 0006 0005 西园路192号 0006 0001000200050006 3
----金色梧桐 0010 0006 金色梧桐 0010 00010002000500060010 4
----科技有限公司 0011 0010 科技有限公司 0011 000100020005000600100011 5
----水富县 0007 0002 水富县 0007 000100020007 2
----两碗乡 0015 0007 两碗乡 0015 0001000200070015 3
----两碗村 0013 0015 两碗村 0013 00010002000700150013 4
----某跨国集团董事长 0012 0013 某跨国集团董事长 0012 000100020007001500130012 5
----昭通市 0003 0001 昭通市 0003 00010003 1
----大理市 0009 0001 大理市 0009 00010009 1
----贵州省 0004 NULL 贵州省 0004 0004 0
----四川省 0008 NULL 四川省 0008 0008 0
----成都市 0014 0008 成都市 0014 00080014 1
*/
--查找子节点(包括本身节点和子节点)
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 ybh='0005'
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(无列名) ybh ebh beizhu ybh ebh level
----五华区 0005 0002 五华区 0005 0005 0
----西园路192号 0006 0005 西园路192号 0006 00050006 1
----金色梧桐 0010 0006 金色梧桐 0010 000500060010 2
----科技有限公司 0011 0010 科技有限公司 0011 0005000600100011 3
*/
--查的父节点(包括本身节点和所有的你节点)
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,ebh,@level from tb where ebh='0005'
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tt(ybh,ebh,level)
select a.ebh,b.ebh+a.ebh,@level
from tb a,@level_tt b
where a.ybh=b.ybh and b.level=@level-1
end
select space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh desc
/*
(无列名) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0005000500020001 3
----昆明市 0002 0001 昆明市 0002 000500050002 2
----五华区 0005 0002 五华区 0005 00050005 1
----西园路192号 0006 0005 西园路192号 0006 0005 0
*/
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/soft_wsx/archive/2009/09/04/4521091.aspx
#7
2005的CTE也试了吗?
#8
指教不敢,因为我比你还菜,
等牛人帮你看吧
等牛人帮你看吧
#9
所有结点
不止一个根结点,
如果是叶子结点,则是结子节点的值,
如果不是叶子,就统计此节点下所有的节点。
#10
乔峰的看看
#11
帮顶 是不是能够在临时的基本表上做的文章?
#12
2005的话用CTE来递归
#13
我现在就是用CTE来做的递归查结点,另一个左连接表用来做统计结点的值来填充这个score.
但cte里用不了聚合函数,不得已才改用递归函数,但效率太差。。
#14
你想要的结果是什么?
#15
--> 测试数据:@tb
create table tb([user_group_id] int,[per_group_id] int,[user_group_name] varchar(10))
insert tb
select 1,0,'总管理员' union all
select 2,1,'一级管理员' union all
select 3,2,'二级管理员' union all
select 4,3,'三级管理员' union all
select 8,4,'四级管理员' union all
select 10,8,'五级管理员'
--2000
---创建函数
CREATE FUNCTION f_Cid(@name varchar(10))
RETURNS @t TABLE(ID varchar(10),Level int)
AS
BEGIN
DECLARE @Level int,@id int
SET @Level=1
set @id=(select [per_group_id] from tb where [user_group_name]=@name )
INSERT @t SELECT @ID,@Level
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t SELECT a.[user_group_id],@Level
FROM tb a,@t b
WHERE a.[per_group_id]=b.id
AND b.Level=@Level-1
END
RETURN
END
GO
--调用函数查询二级管理员及其所有子节点
SELECT a.*
FROM tb a,f_Cid('二级管理员') b
WHERE a.[per_group_id]=b.id
/*
user_group_id per_group_id user_group_name
------------- ------------ ---------------
3 2 二级管理员
4 3 三级管理员
8 4 四级管理员
10 8 五级管理员
(4 行受影响)
*/
--2005
;with t as(
select * from tb where [user_group_name]='二级管理员'
union all
select a.* from tb a ,t where a.[per_group_id]=t.[user_group_id]
)
select * from t
/*
user_group_id per_group_id user_group_name
------------- ------------ ---------------
3 2 二级管理员
4 3 三级管理员
8 4 四级管理员
10 8 五级管理员
(4 行受影响)
*/
是这样的吗?不明白
#16
--查找子节点(包括本身节点和子节点)
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 ybh='0005' --要查找的节点
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
#17
这个情况比较复杂,涉及到这多棵树型结构的查询,我里面有用到CTE
#18
只能给你看一些经典例子了
--测试数据 深度排序
DECLARE @t TABLE(ID char(3),PID char(3),Name nvarchar(10))
INSERT @t SELECT '001',NULL ,'山东省'
UNION ALL SELECT '002','001','烟台市'
UNION ALL SELECT '004','002','招远市'
UNION ALL SELECT '003','001','青岛市'
UNION ALL SELECT '005',NULL ,'四会市'
UNION ALL SELECT '006','005','清远市'
UNION ALL SELECT '007','006','小分市'
--深度排序显示处理
--生成每个节点的编码累计(相同当单编号法的编码)
DECLARE @t_Level TABLE(ID char(3),Level int,Sort varchar(8000))
DECLARE @Level int
SET @Level=0
INSERT @t_Level SELECT ID,@Level,ID
FROM @t
WHERE PID IS NULL
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
FROM @t a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
--显示结果
SELECT a.*
FROM @t a,@t_Level b
WHERE a.ID=b.ID
ORDER BY b.Sort
/*--结果
ID PID Name
------ --------- ----------
001 NULL 山东省
002 001 烟台市
004 002 招远市
003 001 青岛市
005 NULL 四会市
006 005 清远市
007 006 小分市
--*/
--查询指定节点及其所有子节点的函数
CREATE FUNCTION f_Cid(@ID char(3))
RETURNS @t_Level TABLE(ID char(3),Level int)
AS
BEGIN
DECLARE @Level int
SET @Level=1
INSERT @t_Level SELECT @ID,@Level
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level
FROM tb a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
RETURN
END
GO
--调用函数查询002及其所有子节点
SELECT a.*
FROM tb a,f_Cid('002') b
WHERE a.ID=b.ID
/*--结果
ID PID Name
------ ------- ----------
002 001 烟台市
004 002 招远市
--*/
--测试数据
DECLARE @t TABLE(ID char(3),PID char(3),Name nvarchar(10))
INSERT @t SELECT '001',NULL ,'山东省'
UNION ALL SELECT '002','001','烟台市'
UNION ALL SELECT '004','002','招远市'
UNION ALL SELECT '003','001','青岛市'
UNION ALL SELECT '005',NULL ,'四会市'
UNION ALL SELECT '006','005','清远市'
UNION ALL SELECT '007','006','小分市'
--深度排序显示处理
--生成每个节点的编码累计(相同当单编号法的编码)
DECLARE @t_Level TABLE(ID char(3),Level int,Sort varchar(8000))
DECLARE @Level int
SET @Level=0
INSERT @t_Level SELECT ID,@Level,ID
FROM @t
WHERE PID IS NULL
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
FROM @t a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
--显示结果
SELECT SPACE(b.Level*2)+'|--'+a.Name
FROM @t a,@t_Level b
WHERE a.ID=b.ID
ORDER BY b.Sort
/*--结果
|--山东省
|--烟台市
|--招远市
|--青岛市
|--四会市
|--清远市
|--小分市
--*/
--树型结构处理之双编号(广度深度排序)
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000))
insert tb
select '0001',null,'云南省'
union all select '0002','0001','昆明市'
union all select '0003','0001','昭通市'
union all select '0009','0001','大理市'
union all select '0008',null,'四川省'
union all select '0004',null,'贵州省'
union all select '0005','0002','五华区'
union all select '0007','0002','水富县'
union all select '0006','0005','西园路192号'
union all select '0010','0006','金色梧桐3-702'
union all select '0011','0010','昆明越科时空科技有限公司'
union all select '0015','0007','两碗乡'
union all select '0013','0015','两碗村'
union all select '0012','0013','某跨国集团董事长'
union all select '0014','0008','成都市'
--深度排序(模拟单编码法)
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(结果) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0001 0
----昆明市 0002 0001 昆明市 0002 00010002 1
----五华区 0005 0002 五华区 0005 000100020005 2
----西园路192号 0006 0005 西园路192号 0006 0001000200050006 3
----金色梧桐3-702 0010 0006 金色梧桐3-702 0010 00010002000500060010 4
----昆明越科时空科技有限公司 0011 0010 昆明越科时空科技有限公司 0011 000100020005000600100011 5
----水富县 0007 0002 水富县 0007 000100020007 2
----两碗乡 0015 0007 两碗乡 0015 0001000200070015 3
----两碗村 0013 0015 两碗村 0013 00010002000700150013 4
----某跨国集团董事长 0012 0013 某跨国集团董事长 0012 000100020007001500130012 5
----昭通市 0003 0001 昭通市 0003 00010003 1
----大理市 0009 0001 大理市 0009 00010009 1
----贵州省 0004 NULL 贵州省 0004 0004 0
----四川省 0008 NULL 四川省 0008 0008 0
----成都市 0014 0008 成都市 0014 00080014 1
*/
--查找子节点(包括本身节点和子节点)
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 ybh='0005'
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(无列名) ybh ebh beizhu ybh ebh level
----五华区 0005 0002 五华区 0005 0005 0
----西园路192号 0006 0005 西园路192号 0006 00050006 1
----金色梧桐3-702 0010 0006 金色梧桐3-702 0010 000500060010 2
----昆明越科时空科技有限公司 0011 0010 昆明越科时空科技有限公司 0011 0005000600100011 3
*/
/*
标题:查询各节点的父路径函数
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-05-12
地点:广东深圳
*/
/*
原始数据及要求结果如下:
--食品
--水果
--香蕉
--苹果
--蔬菜
--青菜
id pid name
----------- ----------- --------------------
1 0 食品
2 1 水果
3 1 蔬菜
4 2 香蕉
5 2 苹果
6 3 青菜
要求得到各节点的父路径即如下结果:
id pid name 路径
--- --- ----- ---------------
1 0 食品 食品
2 1 水果 食品,水果
3 1 蔬菜 食品,蔬菜
4 2 香蕉 食品,水果,香蕉
5 2 苹果 食品,水果,苹果
6 3 青菜 食品,蔬菜,青菜
*/
create table tb (id int , pid int , name nvarchar(20))
insert into tb values(1 , 0 , '食品')
insert into tb values(2 , 1 , '水果')
insert into tb values(3 , 1 , '蔬菜')
insert into tb values(4 , 2 , '香蕉')
insert into tb values(5 , 2 , '苹果')
insert into tb values(6 , 3 , '青菜')
go
--查询各节点的父路径函数
create function f_pid(@id int) returns varchar(100)
as
begin
declare @re_str as varchar(100)
set @re_str = ''
select @re_str = name from tb where id = @id
while exists (select 1 from tb where id = @id and pid <> 0)
begin
select @id = b.id , @re_str = b.name + ',' + @re_str from tb a , tb b where a.id = @id and a.pid = b.id
end
return @re_str
end
go
select * , dbo.f_pid(id) 路径 from tb order by id
drop table tb
drop function f_pid
#19
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
我要的结果是这样。
1,'',130(10+30+30+50),
2,'1',60(30+30)
3,'2',30
4,'1',50
5,'',40(10+30)
6,'5',30
我要的结果是这样。
#20
小F兄。。
深度排序我有了解过,,
但今天的情况不一样咯。
深度排序我有了解过,,
但今天的情况不一样咯。
#21
呵呵 我不是很会 SORRY
#22
别这样咯~~
#23
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
我要的结果是这样。
#24
这个找石头哥帮你搞定。
#25
;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
#26
小梁P,果然厉害,,把统计移到外层,,我咋没有想到呢。。
#27
#29
的确不错.
#30
这样行吗?
双编号逐级汇总
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
*/
#31
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
*/
#32
厉害,学习.
#33
再定义一个中间表。记录父子关系,每次统计的时候从中间表中查询所有子节点记录,然后再统计。希望这个思路可以帮到你。
例如:
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
例如:
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
#34
学习
#35
进来学习
#36
参看:
使用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
使用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
#37
10+30+30+50 结果不是120吗?130怎么出来的,我纠结了好久。
#38
同意楼上,我也想知道130是怎么算出来的?希望赐教!
#39
好...........
#40
好............
#1
sf
#2
咋一看,原来是火鸟大侠
#3
db
#4
小虾是来诚心请教各位的~~多多指教。
#5
你要什么结果 ,只要根? 还是任意节点?
#6
/*看下下
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 Copyright (c)
1988-2008 Microsoft Corporation Enterprise Evaluation Edition on Windows NT 5.1 <X86>
(Build 2600: Service Pack 3)
愿和大家共同进步
如有雷同、实属巧合
●●●●●2009-09-03 17:47:36.077●●●●●
★★★★★soft_wsx★★★★★
*/
--树型结构处理之双编号(广度深度排序)
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000))
insert tb
select '0001',null,'云南省'
union all select '0002','0001','昆明市'
union all select '0003','0001','昭通市'
union all select '0009','0001','大理市'
union all select '0008',null,'四川省'
union all select '0004',null,'贵州省'
union all select '0005','0002','五华区'
union all select '0007','0002','水富县'
union all select '0006','0005','西园路192号'
union all select '0010','0006','金色梧桐'
union all select '0011','0010','科技有限公司'
union all select '0015','0007','两碗乡'
union all select '0013','0015','两碗村'
union all select '0012','0013','某跨国集团董事长'
union all select '0014','0008','成都市'
--select * from tb
--广度排序(先显示第一层节点,再显示第二次节点......)
--定义辅助表
declare @level_tb table(bh nvarchar(10),level int)
declare @level int
set @level=0
insert @level_tb(bh,level)
select ybh,@level from tb where ebh is null
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tb(bh,level)
select ybh,@level
from tb a,@level_tb b
where a.ebh=b.bh
and b.level=@level-1
end
select a.*,b.* from tb a,@level_tb b where a.ybh=b.bh order by level
/*
ybh ebh beizhu bh level
0001 NULL 云南省 0001 0
0008 NULL 四川省 0008 0
0004 NULL 贵州省 0004 0
0002 0001 昆明市 0002 1
0003 0001 昭通市 0003 1
0009 0001 大理市 0009 1
0014 0008 成都市 0014 1
0005 0002 五华区 0005 2
0007 0002 水富县 0007 2
0006 0005 西园路192号 0006 3
0015 0007 两碗乡 0015 3
0010 0006 金色梧桐 0010 4
0013 0015 两碗村 0013 4
0011 0010 科技有限公司 0011 5
0012 0013 某跨国集团董事长 0012 5
*/
--深度排序(模拟单编码法)
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*(无列名) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0001 0
----昆明市 0002 0001 昆明市 0002 00010002 1
----五华区 0005 0002 五华区 0005 000100020005 2
----西园路192号 0006 0005 西园路192号 0006 0001000200050006 3
----金色梧桐 0010 0006 金色梧桐 0010 00010002000500060010 4
----科技有限公司 0011 0010 科技有限公司 0011 000100020005000600100011 5
----水富县 0007 0002 水富县 0007 000100020007 2
----两碗乡 0015 0007 两碗乡 0015 0001000200070015 3
----两碗村 0013 0015 两碗村 0013 00010002000700150013 4
----某跨国集团董事长 0012 0013 某跨国集团董事长 0012 000100020007001500130012 5
----昭通市 0003 0001 昭通市 0003 00010003 1
----大理市 0009 0001 大理市 0009 00010009 1
----贵州省 0004 NULL 贵州省 0004 0004 0
----四川省 0008 NULL 四川省 0008 0008 0
----成都市 0014 0008 成都市 0014 00080014 1
*/
--查找子节点(包括本身节点和子节点)
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 ybh='0005'
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(无列名) ybh ebh beizhu ybh ebh level
----五华区 0005 0002 五华区 0005 0005 0
----西园路192号 0006 0005 西园路192号 0006 00050006 1
----金色梧桐 0010 0006 金色梧桐 0010 000500060010 2
----科技有限公司 0011 0010 科技有限公司 0011 0005000600100011 3
*/
--查的父节点(包括本身节点和所有的你节点)
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,ebh,@level from tb where ebh='0005'
while @@ROWCOUNT>0
begin
set @level=@level+1
insert @level_tt(ybh,ebh,level)
select a.ebh,b.ebh+a.ebh,@level
from tb a,@level_tt b
where a.ybh=b.ybh and b.level=@level-1
end
select space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh desc
/*
(无列名) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0005000500020001 3
----昆明市 0002 0001 昆明市 0002 000500050002 2
----五华区 0005 0002 五华区 0005 00050005 1
----西园路192号 0006 0005 西园路192号 0006 0005 0
*/
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/soft_wsx/archive/2009/09/04/4521091.aspx
#7
2005的CTE也试了吗?
#8
指教不敢,因为我比你还菜,
等牛人帮你看吧
等牛人帮你看吧
#9
所有结点
不止一个根结点,
如果是叶子结点,则是结子节点的值,
如果不是叶子,就统计此节点下所有的节点。
#10
乔峰的看看
#11
帮顶 是不是能够在临时的基本表上做的文章?
#12
2005的话用CTE来递归
#13
我现在就是用CTE来做的递归查结点,另一个左连接表用来做统计结点的值来填充这个score.
但cte里用不了聚合函数,不得已才改用递归函数,但效率太差。。
#14
你想要的结果是什么?
#15
--> 测试数据:@tb
create table tb([user_group_id] int,[per_group_id] int,[user_group_name] varchar(10))
insert tb
select 1,0,'总管理员' union all
select 2,1,'一级管理员' union all
select 3,2,'二级管理员' union all
select 4,3,'三级管理员' union all
select 8,4,'四级管理员' union all
select 10,8,'五级管理员'
--2000
---创建函数
CREATE FUNCTION f_Cid(@name varchar(10))
RETURNS @t TABLE(ID varchar(10),Level int)
AS
BEGIN
DECLARE @Level int,@id int
SET @Level=1
set @id=(select [per_group_id] from tb where [user_group_name]=@name )
INSERT @t SELECT @ID,@Level
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t SELECT a.[user_group_id],@Level
FROM tb a,@t b
WHERE a.[per_group_id]=b.id
AND b.Level=@Level-1
END
RETURN
END
GO
--调用函数查询二级管理员及其所有子节点
SELECT a.*
FROM tb a,f_Cid('二级管理员') b
WHERE a.[per_group_id]=b.id
/*
user_group_id per_group_id user_group_name
------------- ------------ ---------------
3 2 二级管理员
4 3 三级管理员
8 4 四级管理员
10 8 五级管理员
(4 行受影响)
*/
--2005
;with t as(
select * from tb where [user_group_name]='二级管理员'
union all
select a.* from tb a ,t where a.[per_group_id]=t.[user_group_id]
)
select * from t
/*
user_group_id per_group_id user_group_name
------------- ------------ ---------------
3 2 二级管理员
4 3 三级管理员
8 4 四级管理员
10 8 五级管理员
(4 行受影响)
*/
是这样的吗?不明白
#16
--查找子节点(包括本身节点和子节点)
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 ybh='0005' --要查找的节点
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
#17
这个情况比较复杂,涉及到这多棵树型结构的查询,我里面有用到CTE
#18
只能给你看一些经典例子了
--测试数据 深度排序
DECLARE @t TABLE(ID char(3),PID char(3),Name nvarchar(10))
INSERT @t SELECT '001',NULL ,'山东省'
UNION ALL SELECT '002','001','烟台市'
UNION ALL SELECT '004','002','招远市'
UNION ALL SELECT '003','001','青岛市'
UNION ALL SELECT '005',NULL ,'四会市'
UNION ALL SELECT '006','005','清远市'
UNION ALL SELECT '007','006','小分市'
--深度排序显示处理
--生成每个节点的编码累计(相同当单编号法的编码)
DECLARE @t_Level TABLE(ID char(3),Level int,Sort varchar(8000))
DECLARE @Level int
SET @Level=0
INSERT @t_Level SELECT ID,@Level,ID
FROM @t
WHERE PID IS NULL
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
FROM @t a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
--显示结果
SELECT a.*
FROM @t a,@t_Level b
WHERE a.ID=b.ID
ORDER BY b.Sort
/*--结果
ID PID Name
------ --------- ----------
001 NULL 山东省
002 001 烟台市
004 002 招远市
003 001 青岛市
005 NULL 四会市
006 005 清远市
007 006 小分市
--*/
--查询指定节点及其所有子节点的函数
CREATE FUNCTION f_Cid(@ID char(3))
RETURNS @t_Level TABLE(ID char(3),Level int)
AS
BEGIN
DECLARE @Level int
SET @Level=1
INSERT @t_Level SELECT @ID,@Level
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level
FROM tb a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
RETURN
END
GO
--调用函数查询002及其所有子节点
SELECT a.*
FROM tb a,f_Cid('002') b
WHERE a.ID=b.ID
/*--结果
ID PID Name
------ ------- ----------
002 001 烟台市
004 002 招远市
--*/
--测试数据
DECLARE @t TABLE(ID char(3),PID char(3),Name nvarchar(10))
INSERT @t SELECT '001',NULL ,'山东省'
UNION ALL SELECT '002','001','烟台市'
UNION ALL SELECT '004','002','招远市'
UNION ALL SELECT '003','001','青岛市'
UNION ALL SELECT '005',NULL ,'四会市'
UNION ALL SELECT '006','005','清远市'
UNION ALL SELECT '007','006','小分市'
--深度排序显示处理
--生成每个节点的编码累计(相同当单编号法的编码)
DECLARE @t_Level TABLE(ID char(3),Level int,Sort varchar(8000))
DECLARE @Level int
SET @Level=0
INSERT @t_Level SELECT ID,@Level,ID
FROM @t
WHERE PID IS NULL
WHILE @@ROWCOUNT>0
BEGIN
SET @Level=@Level+1
INSERT @t_Level SELECT a.ID,@Level,b.Sort+a.ID
FROM @t a,@t_Level b
WHERE a.PID=b.ID
AND b.Level=@Level-1
END
--显示结果
SELECT SPACE(b.Level*2)+'|--'+a.Name
FROM @t a,@t_Level b
WHERE a.ID=b.ID
ORDER BY b.Sort
/*--结果
|--山东省
|--烟台市
|--招远市
|--青岛市
|--四会市
|--清远市
|--小分市
--*/
--树型结构处理之双编号(广度深度排序)
if OBJECTPROPERTY(object_id('tb'),'isusertable')<>0
drop table tb
create table tb(ybh nvarchar(10),ebh nvarchar(10),beizhu nvarchar(1000))
insert tb
select '0001',null,'云南省'
union all select '0002','0001','昆明市'
union all select '0003','0001','昭通市'
union all select '0009','0001','大理市'
union all select '0008',null,'四川省'
union all select '0004',null,'贵州省'
union all select '0005','0002','五华区'
union all select '0007','0002','水富县'
union all select '0006','0005','西园路192号'
union all select '0010','0006','金色梧桐3-702'
union all select '0011','0010','昆明越科时空科技有限公司'
union all select '0015','0007','两碗乡'
union all select '0013','0015','两碗村'
union all select '0012','0013','某跨国集团董事长'
union all select '0014','0008','成都市'
--深度排序(模拟单编码法)
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(结果) ybh ebh beizhu ybh ebh level
----云南省 0001 NULL 云南省 0001 0001 0
----昆明市 0002 0001 昆明市 0002 00010002 1
----五华区 0005 0002 五华区 0005 000100020005 2
----西园路192号 0006 0005 西园路192号 0006 0001000200050006 3
----金色梧桐3-702 0010 0006 金色梧桐3-702 0010 00010002000500060010 4
----昆明越科时空科技有限公司 0011 0010 昆明越科时空科技有限公司 0011 000100020005000600100011 5
----水富县 0007 0002 水富县 0007 000100020007 2
----两碗乡 0015 0007 两碗乡 0015 0001000200070015 3
----两碗村 0013 0015 两碗村 0013 00010002000700150013 4
----某跨国集团董事长 0012 0013 某跨国集团董事长 0012 000100020007001500130012 5
----昭通市 0003 0001 昭通市 0003 00010003 1
----大理市 0009 0001 大理市 0009 00010009 1
----贵州省 0004 NULL 贵州省 0004 0004 0
----四川省 0008 NULL 四川省 0008 0008 0
----成都市 0014 0008 成都市 0014 00080014 1
*/
--查找子节点(包括本身节点和子节点)
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 ybh='0005'
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 space(b.level*2)+'----'+a.beizhu,a.*,b.*
from tb a,@level_tt b
where a.ybh=b.ybh
order by b.ebh
/*
(无列名) ybh ebh beizhu ybh ebh level
----五华区 0005 0002 五华区 0005 0005 0
----西园路192号 0006 0005 西园路192号 0006 00050006 1
----金色梧桐3-702 0010 0006 金色梧桐3-702 0010 000500060010 2
----昆明越科时空科技有限公司 0011 0010 昆明越科时空科技有限公司 0011 0005000600100011 3
*/
/*
标题:查询各节点的父路径函数
作者:爱新觉罗·毓华(十八年风雨,守得冰山雪莲花开)
时间:2008-05-12
地点:广东深圳
*/
/*
原始数据及要求结果如下:
--食品
--水果
--香蕉
--苹果
--蔬菜
--青菜
id pid name
----------- ----------- --------------------
1 0 食品
2 1 水果
3 1 蔬菜
4 2 香蕉
5 2 苹果
6 3 青菜
要求得到各节点的父路径即如下结果:
id pid name 路径
--- --- ----- ---------------
1 0 食品 食品
2 1 水果 食品,水果
3 1 蔬菜 食品,蔬菜
4 2 香蕉 食品,水果,香蕉
5 2 苹果 食品,水果,苹果
6 3 青菜 食品,蔬菜,青菜
*/
create table tb (id int , pid int , name nvarchar(20))
insert into tb values(1 , 0 , '食品')
insert into tb values(2 , 1 , '水果')
insert into tb values(3 , 1 , '蔬菜')
insert into tb values(4 , 2 , '香蕉')
insert into tb values(5 , 2 , '苹果')
insert into tb values(6 , 3 , '青菜')
go
--查询各节点的父路径函数
create function f_pid(@id int) returns varchar(100)
as
begin
declare @re_str as varchar(100)
set @re_str = ''
select @re_str = name from tb where id = @id
while exists (select 1 from tb where id = @id and pid <> 0)
begin
select @id = b.id , @re_str = b.name + ',' + @re_str from tb a , tb b where a.id = @id and a.pid = b.id
end
return @re_str
end
go
select * , dbo.f_pid(id) 路径 from tb order by id
drop table tb
drop function f_pid
#19
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
我要的结果是这样。
1,'',130(10+30+30+50),
2,'1',60(30+30)
3,'2',30
4,'1',50
5,'',40(10+30)
6,'5',30
我要的结果是这样。
#20
小F兄。。
深度排序我有了解过,,
但今天的情况不一样咯。
深度排序我有了解过,,
但今天的情况不一样咯。
#21
呵呵 我不是很会 SORRY
#22
别这样咯~~
#23
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
我要的结果是这样。
#24
这个找石头哥帮你搞定。
#25
;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
#26
小梁P,果然厉害,,把统计移到外层,,我咋没有想到呢。。
#27
#28
#29
的确不错.
#30
这样行吗?
双编号逐级汇总
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
*/
#31
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
*/
#32
厉害,学习.
#33
再定义一个中间表。记录父子关系,每次统计的时候从中间表中查询所有子节点记录,然后再统计。希望这个思路可以帮到你。
例如:
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
例如:
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
#34
学习
#35
进来学习
#36
参看:
使用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
使用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
#37
10+30+30+50 结果不是120吗?130怎么出来的,我纠结了好久。
#38
同意楼上,我也想知道130是怎么算出来的?希望赐教!
#39
好...........
#40
好............