原文链接地址http://www.cnblogs.com/sweting/archive/2009/06/08/1498483.html
在工作中遇到一个问题,是需要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 [email protected]
while @@rowcount>0
begin
set
@[email protected]+1
insert into @t
select a.*,@i from t a left join @t b on
a.upperid=b.id
where [email protected]
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 部门[email protected] and 部门!=上级部门
while exists(select 1 from tb where
部门[email protected] and 部门!=上级部门)
begin
insert @ta select 上级部门 from tb where 部门[email protected]
and 部门!=上级部门
select @name=上级部门 from tb where 部门[email protected] 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)
但是可以从部门到上级部门,却不知道怎么修改成为从上级部门到部门.所以最终没有采用