在工作中遇到一个问题,是需要sql递归查询的.不懂,于是到csdn上去问,那里的效率真是非常高,我以前也没在上面问过问题.
问题描述:
我有一个表结构如下: id upperid 1 2 3 2 4 1 5 3
具体层次不知道,我想用递归sql语句把所有属于某个upperid的数据,包括它的子树,都读出去,请问应该子怎么写? 比如说 upperid =2 那么先找到1,3,然后再由1,3找到4,5
使用sql语句实现
有两位朋友都给了回复:
fa_ge(鶴嘯九天)
Create table t(id int,upperid int) insert into t select 1, 2 union all select 3, 2 union all select 4, 1 union all select 5, 3 select * from t create function aa(@upperid int) returns @t table (id int,upperid int,level int) as begin declare @i int set @i=1 insert into @t select *,@i from t where upperid=@upperid while @@rowcount>0 begin set @i=@i+1 insert into @t select a.*,@i from t a left join @t b on a.upperid=b.id where b.level=@i-1 end return end
select * from dbo.aa(1)
id upperid level ----------- ----------- ----------- 4 1 1
(所影响的行数为 1 行)
select * from dbo.aa(2)
id upperid level ----------- ----------- ----------- 1 2 1 3 2 1 4 1 2 5 3 2
(所影响的行数为 4 行) 这个需要level这个数,否则得不到.
hellowork(一两清风)
----创建测试数据 if object_id('tbTest') is not null drop table tbTest if object_id('spGetChildren') is not null drop proc spGetChildren GO create table tbTest(id int, upperid int) insert tbTest select 1, 2 union all select 3, 2 union all select 4, 1 union all select 5, 3 GO ----创建存储过程 create proc spGetChildren @id int as declare @t table(id int) insert @t select id from tbTest where upperid = @id while @@rowcount > 0 insert @t select a.id from tbTest as a inner join @t as b on a.upperid = b.id and a.id not in(select id from @t) select * from @t GO
----执行存储过程 declare @upperid int set @upperid = 2 EXEC spGetChildren @upperid
----清除测试环境 drop proc spGetChildren drop table tbTest
/*结果 id ----------- 1 3 4 5 */ 这个就符合我的要求了.
不过我需要的是一个函数,于是改写如下;
create function GetChildren (@id varchar(20)) returns @t table(id varchar(20)) as begin insert @t select wayid from tb where upperwayid = @id while @@rowcount > 0 insert @t select a.wayid from tb as a inner join @t as b on a.upperwayid = b.id and a.wayid not in(select id from @t) return end
哈哈,真是爽啊.
csdn问题地址:
http://community.csdn.net/Expert/topic/5731/5731880.xml?temp=.8160211
原来为了解决这个问题,本来想用递归的,在网上看到了下面的资料:
表结构是这样的
部门 上级部门 A B B C C D A A B B C C
求一条SQL语句,根据A查其上级部门,查询结果为 上级部门 B C D
=================================================
用函数 create table tb (部门 varchar(20),上级部门 varchar(20))
insert into tb select 'A','B' union all select 'B','C' union all select 'C','D' union all select 'A','A' union all select 'B','B' union all select 'C','C'
--select * from tb create function test_f (@name varchar(20)) returns @ta table(上级部门 varchar(20)) as begin --select @name=上级部门 from tb where 部门=@name and 部门!=上级部门 while exists(select 1 from tb where 部门=@name and 部门!=上级部门) begin insert @ta select 上级部门 from tb where 部门=@name and 部门!=上级部门 select @name=上级部门 from tb where 部门=@name and 部门!=上级部门 end return end
select * from dbo.test_f('A')
删除: drop function test_f drop table tb
上级部门 -------------------- B C D
(所影响的行数为 3 行)
(转自:http://blog.csdn.net/jackeyabc/archive/2007/03/19/1533775.aspx)
但是可以从部门到上级部门,却不知道怎么修改成为从上级部门到部门.所以最终没有采用