日期:2014-05-19  浏览次数:20517 次

sql语句如何能实现这样的数据显示。
表结构:   表名:   classes

id   主键唯一值
pid   父级id
name   名称

这是表数据
29 0 一级类别名a
30 29 二级类别a
31 29 二级类别b
32 30 三级类别a
33               30                 三级类别b
34               0                 一级类别名b

页面上实现的数据格式如下:

一级类别名a
      二级类别a
      二级类别b
              三级类别a
一级类别b


------解决方案--------------------
描述:讨论如何处理树形数据,排序,新增,修改,复制,删除,数据完整性检查,汇总统计


表结构描述及数据环境:


表名tb,如果修改表名,则相应修改所有数据处理中涉及到的表名tb


id为编号(标识字段+主键),pid为上级编号,name为名称,后面可以自行增加其他字段.


凡是未特殊标注的地方,对自行增加的字段不影响处理结果/*--数据测试环境
表名tb,如果修改表名,则相应修改所有数据处理中涉及到的表名tb
id为编号(标识字段+主键)
pid为上级编号
name为名称,后面可以自行增加其他字段.

凡是未特殊标注的地方,对自行增加的字段不影响处理结果


--表环境

create table tb(id int identity(1,1) not null constraint PK_tb primary key clustered
,pid int,name varchar(20))
insert into 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


--处理中需要使用的函数及存储过程

--1.自定义函数--获取编码累计
create function f_getmergid(@id int)
returns varchar(8000)
as
begin
declare @re varchar(8000),@pid int

--为了数字排序正常,需要统一编码宽度
declare @idlen int,@idheader varchar(20)
select @idlen=max(len(id))
,@idheader=space(@idlen)
from tb

--得到编码累计
set @re=right(@idheader+cast(@id as varchar),@idlen)
select @pid=pid from tb where id=@id
while @@rowcount> 0
select @re=right(@idheader+cast(@pid as varchar),@idlen)+ ', '+@re
,@pid=pid from tb where id=@pid
return(@re)
end
go


--2.自定义函数--检测某个编码出发,是否被循环引用
create function f_chkid(@id int)
returns bit --循环,返回1,否则返回0
as
begin
declare @re bit,@pid int

set @re=0

--检测
select @pid=pid from tb where id=@id
while @@rowcount> 0
begin
if @pid=@id
begin
set @re=1
goto lbErr
end
select @pid=pid from tb where id=@pid
end

lbErr:
return(@re)
end
go

/*--数据复制

如果表中包含自定义字段,需要修改存储过程
存在嵌套不超过32层的问题.
--*/

--3.复制指定结点下的子结点到另一个结点下
create proc p_copy
@s_id int, --复制该项下的所有子项
@d_id int, --复制到此项下
@new_id int --新增加项的开始编号
as
declare @nid int,@oid int,@name varchar(20)
select id,name into #temp from tb where pid=@s_id and id <@new_id
while exists(select 1 from #temp)
begin
select @oid=id,@name=name from #temp
insert into tb values(@d_id,@name)
set @nid=@@identity
exec p_copy @oid,@nid,@new_id
delete from #temp where id=@oid
end
go

--4.批量复制的存储过程--复制指定结点及其下面的所有子结点,并生成新结点
create proc p_copystr
@s_id varchar(8000) --要复制项的列表,用逗号分隔
as
declare @nid int,@oid int,@name var