`
逆风的香1314
  • 浏览: 1431985 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

树形数据的处理

阅读更多

/*--表结构描述及数据环境:

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

--邹建2003.12(引用请保留此信息)--*/

--测试数据
create table tb(
id int identity(1,1) not null constraint PK_tb primary key clustered,
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


--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 varchar(20)
set @s_id=','+@s_id+','
select id,name into #temp from tb
where charindex(','+cast(id as varchar)+',', @s_id)>0
while exists(select 1 from #temp)
begin
 select @oid=id,@name=name from #temp
 insert into tb values(@oid,@name)
 set @nid=@@identity
 exec p_copy @oid,@nid,@nid
 delete from #temp where id=@oid
end
go

--5.得到指定id的子id列表
create function f_getchildid(@id int)
returns @re table(id int)
as
begin
 insert into @re select id from tb where pid=@id
 while @@rowcount>0
  insert into @re select a.id
   from tb a inner join @re b on a.pid=b.id
   where a.id not in(select id from @re)
 return
end
go


--6.得到指定id的父id列表
create function f_getparentid(@id int)
returns @re table(id int)
as
begin
 declare @pid int
 select @pid=pid from tb where id=@id
 while @pid<>0
 begin
  insert into @re values(@pid)
  select @pid=pid from tb where id=@pid
 end
 return
end
go


--7.删除指定结点

create proc p_delete
@id int,    --要删除的id
@deletechild bit=0  --是否删除子 1.删除子,0.如果@id有子,则删除失败.
as
 if @deletechild=1
  delete from tb where dbo.f_getmergid(id) like dbo.f_getmergid(@id)+'%'
 else
  if exists(select 1 from tb where pid=@id)
   goto lbErr
  else
   delete from tb where id=@id 
return

lbErr:
 RAISERROR ('该结点下有子结点,不能删除', 16, 1)
go


--8.得到编码累计及编码级别表,这个是针对全表的,主要是应该于全表处理:

create function f_getbmmerg()

returns @re table(id int,idmerg varchar(8000),level int)

as

begin
         declare @idlen int,@idheader varchar(20), @level int
         select @idlen=max(len(id)),@idheader=space(@idlen) from tb
         set @level=1
         insert into @re select id,right(@idheader+cast(id as varchar),@idlen),@level
                   from tb where pid=0
         while @@rowcount>0
         begin
                   set @level=@level+1
                   insert into @re select b.id,a.idmerg+','+right(@idheader+cast(b.id as varchar),@idlen),@level
                            from @re a inner join tb b on a.id=b.pid
                            where a.level=@level-1
         end
return
end
go


--应用:

/*--数据显示排序--*/
--分级显示--横向,先一级,后二级...
select * from tb order by pid

--分级显示--纵向
select * from tb order by dbo.f_getmergid(id)
go

/*--数据统计--*/
--分级统计,每个地区下的明细地区数
select *,
 明细地区数=(select count(*) from tb where dbo.f_getmergid(id) like dbo.f_getmergid(a.id)+',%')
from tb a order by dbo.f_getmergid(id)

go
/*--数据新增,修改
 
 数据新增,修改(包括修改所属的类别)没有什么技巧
 ,只需要检查所属的上级是否存在就行了.这个可以简单的用下面的语句来解决:
 if exists(select 1 from tb where id=@id) print '存在' else print '不存在'
--*/


--删除'美国'的数据
--exec p_delete 2  --不包含子,因为有美国下有子,所以删除会出错
exec p_delete 2,1 --包含子,将删除美国及所有数据
go


原文参见我在CSDN上发表的贴子

http://expert.csdn.net/Expert/topic/2285/2285830.xml?temp=.1212885

分享到:
评论

相关推荐

    sql树形数据处理示例(Jet wang 最新整理)

    以下是对SQL树形数据处理的一些关键知识点的详细说明: 1. **递归查询**: SQL中的递归查询是处理树形数据的核心方法。通过自连接,我们可以遍历层级关系。例如,使用`WITH RECURSIVE`语句(在PostgreSQL、MySQL ...

    基于模型空间的树形数据处理方法.pdf

    标题《基于模型空间的树形数据处理方法》与描述《资源达人分享计划》指向一个专业技术文档,聚焦于树形数据处理的创新方法。标签“数据处理 大数据 数据分析 参考文献 专业指导”表明该文档旨在提供数据处理与分析...

    数据库树形数据处理方案.pdf

    《数据库树形数据处理方案》 在数据库管理中,树形数据结构是一种常见的数据组织方式,尤其在表示层级关系时非常有用。这个方案主要涉及了树形数据的排序、新增、修改、复制、删除以及数据完整性检查和汇总统计等...

    sql树形数据处理示例

    总结来说,处理SQL中的树形数据需要对递归查询、CTEs以及表自连接等概念有深入理解。通过灵活运用这些技术,我们可以有效地在数据库中构建和查询层级关系,满足各种业务需求。在实际项目中,应根据数据规模和查询...

    js 树形结构数据遍历条件判断删除对应数据.pdf

    这个函数采用递归方式处理树形数据,可以有效地遍历树的任意深度,并删除满足条件的节点。值得注意的是,这种方法会创建一个新的数据结构,原数据不会被修改,这是因为在JavaScript中,数组和对象都是引用类型,原始...

    Excel树形结构数据导入Oracle数据库(Java)

    在IT行业中,数据库管理和数据处理是至关重要的环节。当我们面对大量结构化数据,例如Excel表格,需要将其导入到关系型数据库如Oracle时,通常会利用编程语言如Java来实现自动化处理。这篇博客“Excel树形结构数据...

    Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)

    数据结构为数组中包含对象–树形结构,用Vue组件的写法实现以下的效果: 树形列表,缩进显示层级,第5级数据加底色,数据样式显色,点击展开折叠数据。本文为用Vue实现方式,另有一篇为用knockout.js的实现方法。 ...

    树形控件拖曳放置及移动_labview_labview树形控件_树形控件(tree)

    在LabVIEW编程环境中,树形控件(Tree Control)是一种常用的数据展示和交互工具,它以层次结构的方式显示数据,用户可以通过展开、折叠节点来查看和操作数据。本教程将详细讲解如何在LabVIEW中使用树形控件进行拖曳...

    java动态树形菜单

    Servlet负责处理请求,可能包括从数据库或者其他数据源获取菜单数据,然后将这些数据组织成树形结构。接着,JSP页面接收Servlet传递的数据,并将其转换为HTML,呈现为树形菜单。 实现步骤如下: 1. **数据模型**:...

    SSH+Easyui之TreeGrid树形展现数据

    3. **Hibernate DAO**:编写DAO类,使用HQL或SQL查询数据库,获取树形数据。 4. **数据转换为JSON**:将Service层获取的数据转换为JSON格式,可以使用Jackson或Gson等库进行转换。 5. **EasyUI TreeGrid配置**:在...

    bootstrap树形下拉框 下拉框树形菜单

    var treeData = [/* 树形数据结构 */]; $('#treeview').treeview({ data: treeData, expandIcon: 'glyphicon glyphicon-minus', collapseIcon: 'glyphicon glyphicon-plus', nodeIcon: 'glyphicon glyphicon-...

    java动态树形菜单与分页

    后端服务器(通常基于Spring MVC或Struts2框架)负责处理请求,查询数据库并返回JSON格式的数据,前端JavaScript将这些数据转换为树形结构展示在页面上。在给定的项目中,可能包含了这样的前后端交互逻辑和数据库...

    把扁平化的数据转换成树形结构的JSON

    在IT行业中,数据的组织和...总之,将扁平化的数据转换成树形结构是JavaScript开发中的常见任务,尤其在处理JSON数据时。通过理解数据结构和递归算法,我们可以有效地完成这个转换,从而更好地管理和操作层次化数据。

    数据结构课程设计-树形目录结构.docx

    数据结构课程设计中,树形目录结构是一种关键的非线性数据结构,它在计算机科学领域,尤其是在操作系统、人工智能和数据库系统中有着广泛的应用。树型结构能够有效地描绘具有层级关系的对象,比如在操作系统中,文件...

    excel树形字典,导入数据库

    "Excel树形字典,导入数据库"这个主题就聚焦于如何将结构化的Excel数据,特别是树形结构的数据,有效地整合到数据库系统中。 首先,我们需要理解什么是"树形字典"。在Excel中,树形字典通常指的是通过表格形式表示...

    labview树形控件的使用

    在LabVIEW中,树形控件是一种非常实用的数据组织和显示工具,它可以帮助用户以层次结构的方式展示和操作数据。在本文中,我们将详细探讨如何在LabVIEW2019中有效地使用树形控件。 首先,树形控件的基本概念。在...

    基于layui实现树形穿梭框

    - 加载数据:使用layui的API加载树形结构的数据,通常是从服务器获取JSON格式的数据,然后调用`layui.tree`方法生成树形结构。 - 绑定事件:监听用户的点击操作,通过`layui.form.on('select')`方法捕获选择变化,...

    关系数据库存储树形结构数据的理想实践

    随着数据量的增大,更应考虑数据索引、查询优化和事务管理等技术,这些都会影响到树形数据在关系数据库中的存储效率和响应时间。 最后,虽然当前文档中出现了部分OCR扫描错误,导致一些文字无法识别,但是不影响...

Global site tag (gtag.js) - Google Analytics