--树形数据查询示例
--作者: 邹建
if exists (select * from dbo.sysobjects where id = object_id(N'[tb]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb]
GO
--示例数据
create table [tb]([id] int identity(1,1),[pid] int,name varchar(20))
insert [tb] select 0,'中国'
union all select 0,'美国'
union all select 0,'加拿大'
union all select 1,'北京'
union all select 1,'上海'
union all select 1,'江苏'
union all select 6,'苏州'
union all select 7,'常熟'
union all select 6,'南京'
union all select 6,'无锡'
union all select 2,'纽约'
union all select 2,'旧金山'
go
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_id]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_id]
GO
/*--树形数据处理
级别及排序字段
--邹建 2003-12(引用请保留此信息)--*/
/*--调用示例
--调用函数实现分级显示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
--*/
create function f_id()
returns @re table([id] int,[level] int,sid varchar(8000))
as
begin
declare @l int
set @l=0
insert @re select [id],@l,right(10000+[id],4)
from [tb] where [pid]=0
while @@rowcount>0
begin
set @l=@l+1
insert @re select a.[id],@l,b.sid+right(10000+a.[id],4)
from [tb] a,@re b
where a.[pid]=b.[id] and b.[level]=@l-1
end
return
end
go
--调用函数实现分级显示
select replicate('-',b.[level]*4)+a.name
from [tb] a,f_id()b
where a.[id]=b.[id]
order by b.sid
go
--删除测试
drop table [tb]
drop function f_id
go
/*--结果
中国
----北京
----上海
----江苏
--------苏州
------------常熟
--------南京
--------无锡
美国
----纽约
----旧金山
加拿大
--*/
--测试数据
create table 表(id int,parentid int,content varchar(10))
insert 表 select 1,0,'aa'
union all select 2,0,'bb'
union all select 3,1,'cc'
union all select 4,1,'aa'
union all select 5,3,'dd'
union all select 6,5,'aa'
union all select 7,2,'aa'
union all select 8,3,'dd'
union all select 9,6,'aa'
go
--处理函数
create function f_tree()
returns @re table(
id int,
level int, --自身节点所处深度
childs int, --所拥有的叶子数
c_level int,--下属(孩子)节点的最大高度
sid varchar(8000) --编码累计
)
as
begin
declare @l int
set @l=1
insert @re(id,level,sid) select id,@l,cast(id as varchar)+','
from 表
where parentid=0
while @@rowcount>0
begin
set @l=@l+1
insert @re(id,level,sid)
select a.id,@l,b.sid+cast(a.id as varchar)+','
from 表 a join @re b
on a.parentid=b.id and b.level=@l-1
end
update a set childs=b.childs,c_level=b.c_level
from @re a,(
select a.id,childs=count(b.id),c_level=isnull(max(b.level),0)
from @re a
left join @re b on b.sid like a.sid+'_%'
group by a.id
)b where a.id=b.id
return
end
go
--调用函数显示结果
select a.*
,自身节点所处深度=b.level
,所拥有的叶子数=b.childs
,[下属(孩子)节点的最大高度]=b.c_level
from 表 a,f_tree() b
where a.id=b.id
order by b.sid
go
--删除测试
drop table 表
drop function f_tree
/*--测试结果
id parentid content 自身节点所处深度 所拥有的叶子数 下属(孩子)节点的最大高度
----------- ----------- ---------- ----------- ----------- -------------
1 0 aa 1 6 5
3 1 cc 2 4 5
5 3 dd 3 2 5
6 5 aa 4 1 5
9 6 aa 5 0 0
8 3 dd 3 0 0
4 1 aa 2 0 0
2 0 bb 1 1 2
7 2 aa 2 0 0
(所影响的行数为 9 行)
--*/