SQL2000树的递归遍历问题?急呀,救命呀

meothfs 2007-09-14 09:32:41
dept_no1 dept_no2
11 101
11 102
11 103
101 10111
102 10122
10111 11111
10122 12111
11111 111111

要转换为下表,想尽办法,最后只有用递归,但是发现sql2000对递归的支持有限,sql2005 还可以使用CTE 有过解决类似问题的大虾,麻烦救命
結果為表:
dept_no1,dept_no2
11 11
11 101
11 102
11 103
11 10111
11 10122
11 12111
11 11111
11 111111
101 101
101 10111
10111 11111
11111 111111
102 102
102 10122
102 12111
103 103



...全文
224 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
110来电 2007-10-14
  • 打赏
  • 举报
回复
小宝
多级仓库的展开树
WarehouseId, UpWarehouseId, WhCode, WhName
仓库ID , 上级仓库ID , 仓库代码,仓库名称

EXECUTE pc_TraversalTree
@SourceSQL='SELECT WarehouseId, UpWarehouseId, WhCode, WhName FROM tblWarehouse'
,@Splitchar=' '

1 0 61 0 WH-01 原辅料仓
2 0 62 0 WH-02 半成品仓
3 62 63 1 WH-03 1号成品仓
4 63 64 2 WH-04 3号成品仓
5 64 65 3 WH-06 外管仓
6 0 66 0 WH-07 办房物料仓
7 0 67 0 WH-08 展厅
8 0 68 0 WH-09 广州成品仓
9 0 69 0 WH-010 2号成品仓
10 0 70 0 WH_PD 盘点测试
11 0 71 0 wh003 损坏仓库

只要你每一行都有指向父节点的ID,都是可以的
这个基本上使用数据结构里的堆栈消除递归,只不过堆栈我用了临时表来代替
如果你有疑问,不如先研究一下堆栈消除递归的原理
110来电 2007-09-14
  • 打赏
  • 举报
回复
--利用堆栈消除递归
IF EXISTS (SELECT name
FROM sysobjects
WHERE name = 'pc_TraversalTree'
AND type = 'P')
DROP PROCEDURE pc_TraversalTree
GO
/*
存储过程描述
Ding
通用的遍历树,深度优先
*/

CREATE PROCEDURE pc_TraversalTree
@rootID int =-1 --要查询的一组,作为返回表的根
,@SourceSQL Text--数据源的查询语句,MeID,ParentID,Col,Col2列有顺序
,@Splitchar nvarchar(50)=''--显示的层次分隔符号
AS

SET NoCount ON
--
declare @top int --当栈顶指针
set @top=0

create table #tmpSource(
AuotID int IDENTITY(1,1),
MeID int,
ParentID int,
Col1 nvarchar(1000),
Col2 nvarchar(1000)
)

-- 行ID ,上层行ID,描述1,描述2
exec('Insert #tmpSource (MeID,ParentID,Col1,Col2)'+@SourceSQL)

create table #tmpOutput(
AutoID int IDENTITY (1, 1),
ParentID int ,
MeID int,
[Level] int,
Col1 nvarchar(1000),
Col2 nvarchar(1000)
)

create table #Stack(
AutoID int IDENTITY (1, 1),
MeID int,
Parent int,
[level] int
)

--根结点进栈

insert #Stack(MeID,[level]) select @rootID,0

declare @StackCount int
set @StackCount=1

--print 'Root is ' + @root

declare @last int

declare @currentParent int


declare @mylevel int

set @currentParent=@rootID

if @rootID=-1
begin
insert #Stack (MeID,Parent,[level])
select MeID,@top ,0 from #tmpSource where ParentID IS NULL order by MeID desc

end

while (@StackCount>0)
begin
--退栈,堆栈表的最后一行为栈顶
--得到当前元素的ID,Parent,level
select @last=Max(AutoID) from #Stack
select top 1 @top=MeID,@currentParent=Parent,@myLevel=[level] from #Stack where AutoID=@last
delete from #Stack where AutoID=@last


--添加行到输出表
insert #tmpOutput (parentID,MeID,[level],Col1,Col2)
select top 1 @currentParent,MeID,@myLevel
,REPLICATE(@SplitChar,@myLevel)+cast(Col1 as nvarchar)
,REPLICATE(@SplitChar,@myLevel)+cast(Col2 as nvarchar)
from #tmpSource where MeID=@top

-- select * from #tmpSource where MeID=@top



--将得到所有子节点和当前父节点进栈,
insert #Stack (MeID,Parent,[level])
select MeID,@top ,@myLevel+1 from #tmpSource where ParentID=@top order by MeID desc


set @StackCount=(select Isnull(Count(*),0) from #Stack)

end

select * from #tmpOutput


GO

/*
调试
*/
EXECUTE pc_TraversalTree
@SourceSQL='SELECT WarehouseId, UpWarehouseId, WhCode, WhName FROM tblWarehouse'
,@Splitchar=' '



--select IDENT_CURRENT('tblMateriel_Size')

--select MeID from #tmpSource where ParentID=7
子陌红尘 2007-09-14
  • 打赏
  • 举报
回复
一句SQL的偶不会,估计也不一定有,那么既然是递归,那就递归吧。
子陌红尘 2007-09-14
  • 打赏
  • 举报
回复
create table test(dept_no1 int,dept_no2 int)
insert into test values(11 ,101 )
insert into test values(11 ,102 )
insert into test values(11 ,103 )
insert into test values(101 ,10111 )
insert into test values(102 ,10122 )
insert into test values(10111,11111 )
insert into test values(10122,12111 )
insert into test values(11111,111111)
go

declare @t table(dept_no1 int,dept_no2 int)

insert into @t(dept_no1,dept_no2)
select t.* from test t

while @@rowcount<>0
begin
insert into @t(dept_no1,dept_no2)
select
a.dept_no1,b.dept_no2
from
test a,@t b
where
a.dept_no2=b.dept_no1
and
not exists(select 1 from @t where dept_no1=a.dept_no1 and dept_no2=b.dept_no2)
end


select * from @t order by dept_no1,dept_no2
go

/*
dept_no1 dept_no2
----------- -----------
11 101
11 102
11 103
11 10111
11 10122
11 11111
11 12111
11 111111
101 10111
101 11111
101 111111
102 10122
102 12111
10111 11111
10111 111111
10122 12111
11111 111111
*/

drop table test
go
meothfs 2007-09-14
  • 打赏
  • 举报
回复
dingoishere(丁丁)
我有一个表,

有三个字段
子节点,目节点,最终根节点


如何用你上面的的过程来验证过程是否正确

22,298

社区成员

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

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