请各位大侠帮忙了,这个sql语句怎么实现?

cqhunter 2006-03-16 08:27:25
有如下的数据,parentid表示父节点id,totalchilren表示该节点有几个子节点,total表示数量
id filecode parentid totalchildren total
1 ws112 0 3 0
2 01 1 1 2
3 02 1 1 2
4 03 1 1 2
5 0101 2 0 3
6 0201 3 0 3
7 0301 4 0 3
我想输入ws112,得到如下的结果:
0101 6(2*3)
0201 6(2*3)
0301 6(2*3)
即不管01、02、03这些节点,直接得到ws112最低级的节点情况,请各位大侠帮忙了。
...全文
276 点赞 收藏 12
写回复
12 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
prcgolf 2006-03-24
up
回复
whulph 2006-03-20
create table A
(
id int,
filecode varchar(10),
parentid int,
totalchildren int,
total int
)

insert A select 1,'ws112',0,3,0
insert A select 2,'01',1,1, 2
insert A select 3,'02',1,1, 2
insert A select 4,'03',1,1, 2
insert A select 5,'0101',2,0, 3
insert A select 6,'0201',3,0, 3
insert A select 7,'0301',4,0, 3
insert A select 8,'04',1,0,5

create function List_Leaf(@filecode varchar(10))
returns @LeafDetail table(filecode varchar(10),num int)
As
begin
declare @TempTable table(id int, filecode varchar(10),parentid int,totalchildren int,total int,lev int,num int)
declare @level int
set @level = 0
insert @TempTable select *,@level,1 from A where filecode = @filecode
while @@RowCount>0
begin
set @level = @level + 1
insert @TempTable select A.*,@level,A.total*(T.num) from @TempTable T,A where T.lev = @level-1 and A.parentid = T.id
end
insert @LeafDetail select filecode,num from @TempTable where totalchildren = 0
return
end

select * from List_Leaf('ws112')
go

测试结果:
filecode num
---------- -----------
04 5
0101 6
0201 6
0301 6

(所影响的行数为 4 行)
回复
cqhunter 2006-03-20
不好意思,我的sql是2000,用不了上面的方法 。请大侠们帮忙阿
回复
zlp321002 2006-03-20
--SQL Sever 2005 用(公共表表达式,实现递归方法)如下:

--测试环境
create table A
(
id int,
filecode varchar(10),
parentid int,
totalchildren int,
total int
)
insert A select 1,'ws112',0,3,0
insert A select 2,'01',1,1, 2
insert A select 3,'02',1,1, 2
insert A select 4,'03',1,1, 2
insert A select 5,'0101',2,0, 3
insert A select 6,'0201',3,0, 3
insert A select 7,'0301',4,0, 3
insert A select 8,'04',1,0,5

--建递归CTE
DECLARE @FILECODE AS VARCHAR(20)
SET @FILECODE='ws112';
WITH ACTE(ID,FILECODE,PARENTID,TOTALCHILDREN,TOTAL,LVL)
AS
(
SELECT ID,FILECODE,PARENTID,TOTALCHILDREN,TOTAL,0
FROM A WHERE FILECODE=@FILECODE
UNION ALL
SELECT TA.ID,TA.FILECODE,TA.PARENTID,TA.TOTALCHILDREN,TA.TOTAL,TB.LVL+1
FROM A TA INNER JOIN ACTE TB
ON TA.PARENTID=TB.ID
)
SELECT FILECODE,值=TOTAL*LVL FROM ACTE WHERE TOTALCHILDREN=0
--结果
/*
FILECODE 值
---------- -----------
04 5
0301 6
0201 6
0101 6

(4 行受影响)
*/
--删除环境 Drop table A
回复
cqhunter 2006-03-20
楼上的办法实现了我需要的功能,不过,用了两个临时表,效率方面让人有点不满意,总之,谢谢了.不过,还是请大家再给我想想更好的办法.
我也有一种方法,效率比上面的好一点:
create table filedir
(
id int,
filecode varchar(10),
pid int,
totalchildren int,
total int
)
insert filedir select 1,'ws112',0,3,0
insert filedir select 2,'01',1,1, 2
insert filedir select 3,'02',1,1, 2
insert filedir select 4,'03',1,1, 2
insert filedir select 5,'0101',2,0, 3
insert filedir select 6,'0201',3,0, 3
insert filedir select 7,'0301',4,0, 3
insert filedir select 8,'0401',1,0, 2
go

--创建用户定义函数
create function f_getChild(@ID VARCHAR(10))
returns @t table(ID VARCHAR(10),PID VARCHAR(10),Level INT)
as
begin
declare @i int,@ret varchar(8000)
set @i = 1
insert into @t select ID,pid,@i from filedir where pid = @ID

while @@rowcount<>0
begin
set @i = @i + 1

insert into @t
select
a.ID,a.PID,@i
from
filedir a,@t b
where
a.PID=b.ID and b.Level = @i-1
end
return
end
go

create function f_getparenttotal(@id int,@topid int)
returns int
as
begin
declare @pid int
declare @re int
set @re=1
select @pid=pid from filedir where id=@id
while @pid>@topid
begin
select @pid=pid,@re=@re*[total] from filedir where id=@pid
end
return @re
end
go

--执行查询,dbo.f_getparenttotal(id,1)和f_getChild(1)代表根节点id

select id,filecode,bb=dbo.f_getparenttotal(id,1)*total from filedir where id in( select ID from dbo.f_getChild(1) where id not in(select pid from filedir))

go

drop function f_getparenttotal
drop function f_getChild
drop table filedir
回复
cqhunter 2006-03-19
scmail81(琳·风の狼)的例子好像只能实现规则的树,还请大大帮忙了,走过路过的高手们也请帮忙了。
我的树是一颗不规则的树,叶子的深度可能不一样
我想实现的目标是:
1、查找到任一节点的全部叶子;
2、然后每一个叶子到目标节点之间的所有节点的total值相乘;
回复
cqhunter 2006-03-19
我举的例子是特例,其实我的树是一颗不规则的树,叶子的深度可能不一样
我想实现的目标是:
1、查找到任一节点的全部叶子;
2、然后每一个叶子到目标节点之间的所有节点的total值相乘;
0101 6(2*3)
0201 6(2*3)
0301 6(2*3)
回复
cqhunter 2006-03-19
谢谢,测试完了再给分
回复
$扫地僧$ 2006-03-18
create table A
(
id int,
filecode varchar(10),
parentid int,
totalchildren int,
total int
)

insert A select 1,'ws112',0,3,0
insert A select 2,'01',1,1, 2
insert A select 3,'02',1,1, 2
insert A select 4,'03',1,1, 2
insert A select 5,'0101',2,0, 3
insert A select 6,'0201',3,0, 3
insert A select 7,'0301',4,0, 3

create Function Find_num(@Code varchar(10))
returns @A table(filecode varchar(10),num int)
as
begin
declare @T table(id int,filecode varchar(10),parentid int,totalchildren int,total int,lev int,num int)
declare @lev int
set @lev=1
insert @T select id,filecode,parentid,totalchildren,total,@lev as lev,@lev as num from A where filecode=@Code
while @@rowcount>0
begin
set @lev=@lev+1
insert @T select A1.id,A1.filecode,A1.parentid,A1.totalchildren,A1.total,@lev,A1.total*T.num from A A1, (select * from @T where lev=@lev-1) T where T.id=A1.parentid
end
insert @A select T.filecode,T.num from @T T where T.lev=(select top 1 lev from @T order by lev DESC )
return
end

select * from dbo.Find_num('ws112')
回复
cqhunter 2006-03-18
我可能没有说明白自己的意思,我想取得目录树的全部叶子,然后每一个叶子到根节点之间的所有节点的total值相乘即()除开根节点
0101 6(2*3)
0201 6(2*3)
0301 6(2*3)
回复
cqhunter 2006-03-16
通过ws112,找到无子节点的0101、0201、0301,然后把total的值相乘,不就是上面的结果了吗?还请楼上的大侠帮忙了。
回复
ReViSion 2006-03-16
输入ws112
得到0101 6(2*3)
0201 6(2*3)
0301 6(2*3)

都不知道你是怎么得来的
0201 6(2*3)
0301 6(2*3)
好像都不是他的子节点哦,
回复
相关推荐
发帖
疑难问题
创建于2007-09-28

2.1w+

社区成员

MS-SQL Server 疑难问题
申请成为版主
帖子事件
创建了帖子
2006-03-16 08:27
社区公告
暂无公告