`

一道 SQL 题 ... (关于树型结构的在关系表中的存储及其应用处理)

 
阅读更多

相关讨论连接:
http://expert.csdn.net/Expert/TopicView1.asp?id=1477009
原题:
表:
Tree (ID [Integer],ParentID [Integer],Remark [varchar])

INSERT INTO Tree (ID,ParentID)
SELECT 1,0
UNION ALL
SELECT 2,1
UNION ALL
SELECT 3,1
UNION ALL
SELECT 4,2
UNION ALL
SELECT 5,4
UNION ALL
SELECT 6,5
UNION ALL
SELECT 7,2

T(F1,......)
INSERT INTO T (F1)
SELECT 1
UNION ALL
SELECT 5
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 1
UNION ALL
SELECT 7
UNION ALL
SELECT 6
UNION ALL
SELECT 4
UNION ALL
SELECT 5
UNION ALL
SELECT 3
UNION ALL
SELECT 4
UNION ALL
SELECT 1
UNION ALL
SELECT 7
UNION ALL
SELECT 6
UNION ALL
SELECT 4


参考 Tree 表中的父子关系,"祖先"的记录数要包括所有"后代"的记录数,统计 T 表中 F1 各个取值的记录数
ID Counts
1 15
2 10
3 2
4 8
5 4
6 2
7 2


答案及简单分析:

/*
看了前几个人的答案,似乎都把问题想复杂了"游标"、"临时表"、"递归"。
"游标"、"临时表" 完全可以不用!
"递归" 思想当然应是解决树型结构的该想到的方法!
但是 T-SQL 的嵌套层次最多只能到 32!
icevi(按钮工厂) 的建议是非常值得提倡的,尽管 ID,ParentID 对于仅存储是足够经济的,
但是若用其提供表现形式,性能的确不会太好!
许多高效的树型结构论坛也确实是存储并维护各个节点的层次信息的数据,这样
显示起来仅需一条 SQL 即可!
下面是我的参考答案,两个自定义函数功能几乎一样,都是运算出前面所提的,
应最好主动维护的"层次信息":

方法一: UDF 递归实现! 有 32 层嵌套限制
*/

alter FUNCTION dbo.Get32Ancestors
(@X integer)
RETURNS VARCHAR(250)
AS
BEGIN
DECLARE @ID integer
DECLARE @ReturnValue VARCHAR(250)

SELECT TOP 1 @ID = ParentID
FROM tree
WHERE [id] = @X

IF @ID <> @X
BEGIN
SELECT @ReturnValue = cast(ISNULL(dbo.Get32Ancestors(@ID),'') as varchar) + '-'+ cast(@X as varchar)
END
ELSE SET @ReturnValue = @ID

RETURN @ReturnValue
END

go
/*
2003-3-5
方法二: 无任何限制,若层次太深,效率当然不会高(好像也没更好的办法)
改进了一下:
1.正常节点均从0显示! 0-1-3

2.断码 显示 -7-8-9-10
3.GetAllAncestors(不存在的节点)返回NULL
4.GetAllAncestors(根节点)返回 0-自己
5.死循环点显示: 4-5-6-4-8

*/

alter function GetAllAncestors (@X integer)
returns varchar(1000)
as
begin
declare @ReturnValue varchar(1000)
declare @ID integer
declare @ParentID integer

set @ID = -1

select top 1 @ID=isnull([ID],0),@ParentID = isnull([ParentID],0)
from tree
where ID = @X

while @id <> @parentid and @parentid <> 0 and @ID >0
and '-' + isnull(@ReturnValue,'') +'-' not like '%-' + cast(@id as varchar) + '-%'
begin
if @ReturnValue is not null
set @ReturnValue = '-' + @ReturnValue
set @ReturnValue= cast(@id as varchar) + isnull(@ReturnValue,'')
set @id = -1
select top 1 @ID=isnull([ID],0),@ParentID = isnull([ParentID],0)
from tree
where ID = @parentid
end

set @ReturnValue = '-' + @ReturnValue

if @id>0
set @ReturnValue = cast(@id as varchar) + isnull(@ReturnValue,'')

if @parentid =0 or @id = @parentid
set @ReturnValue = '0-' + isnull(@ReturnValue,'')

return(@ReturnValue)
--select dbo.GetAllAncestors(10)
end


go

/*
方法一是"高手"的惯性思维把简单的问题搞复杂了,"太累"!
方法二是思路简单清晰,不但是"菜鸟"首选,"高手"也应反思!

若是本题分为两问:
1.求各节点层次信息
2.求属各节点含后代的记录数

可能大家就会受到一些启发!
函数定义完,下面就应该和 icevi(按钮工厂) 同志的答案异曲同工、不谋而和了
*/

select id,dbo.GetAllAncestors(id)
,(select count(*)
from T
where '-' + dbo.GetAllAncestors(f1) + '-' like '%-' + cast(tree.id as varchar) + '-%')
from tree

select id,dbo.Get32Ancestors(id)
,(select count(*)
from T
where '-' + dbo.Get32Ancestors(f1) + '-' like '%-' + cast(tree.id as varchar) + '-%')
from tree

/*
另外还要说一下封装的程度的问题,具体情况具体分析,
本题就不适合定义函数直接得到最终结果!
以上答案仅供参考!!
欢迎继续参与讨论!
*/

分享到:
评论

相关推荐

    Node.js-tre创建文件树型结构展示

    在Node.js开发中,我们经常会遇到需要处理文件系统(filesystem)的情况,比如读取、写入、移动文件等。在这些任务中,如果文件组织成目录树状结构,那么理解和展示这种结构会变得尤为重要。"tre"是一个Node.js模块...

    java递归树型结构通用数据库

    在Java递归树型结构通用数据库中,使用关系型数据库来存储部门信息,数据库表结构设计包括部门表、用户表、部门用户表等,通过这些表之间的关系实现树型结构的部门管理。 6. 递归算法实现 在Java递归树型结构通用...

    教你如何用java开发树型结构

    5. **J2EE服务端处理**:在J2EE环境中,树型结构的数据通常存储在数据库中。你可以使用Java的持久化框架,如Hibernate或JPA,来操作这些数据。服务端需要提供RESTful API或者Servlets,以便客户端(如JSP页面)请求...

    树型数据结构在铁路车站信号计算机联锁系统中的应用.pdf

    在探讨“树型数据结构在铁路车站信号计算机联锁系统中的应用”这一主题时,我们首先需要了解树型数据结构的基本概念以及在铁路车站信号系统中的应用场景。树型数据结构是一类非线性数据结构,它的每一个节点可以有两...

    js做的树型结构javascript作的树型结构javascript作的树型结构

    js做的树型结构,应该是很好的,javascript作的树型结构javascript作的树型结构javascript作的树型结构javascript作的树型结构javascript作的树型结构javascript作的树型结构javascript作的树型结构javascript作的树型...

    树型数据结构在测井软件中的应用.pdf

    标题《树型数据结构在测井软件中的应用》表明了文章的主题是讨论在测井软件中应用树型...同时,由于树型数据结构具有很好的层次性和递归性,因此在处理具有明显层级关系的数据时,它能提供非常直观和高效的解决方案。

    pb9 datawindow treeview 树型结构

    通过以上步骤,我们可以利用PB9的DataWindow创建一个自定义的TreeView,虽然不如原生的TreeView控件那么直观和易于维护,但这种实现方式可以提供更大的灵活性,特别是在处理特定需求或旧系统升级时。不过,对于新...

    caidan.rar_伸展树_树型菜单

    在IT领域,树型菜单是一种常见的用户界面元素,它用于组织和展示层级关系的数据,比如在文件管理系统、网站导航或软件应用中。伸展树,也称为可折叠/可伸展树,是树型菜单的一个特定实现,允许用户通过点击图标...

    Delphi中数据库关联树型结构生成与同步数据维护.zip_数据同步_数据库关联_数据维护_树型结构生成

    在Delphi编程环境中,数据库关联树型结构的生成与同步数据维护是开发高效数据库应用程序的重要环节。本资料主要探讨了如何在Windows XP操作系统下,利用Delphi 7进行相关操作。 首先,我们要理解数据库关联的概念。...

    winform树型结构

    在C#编程中,WinForm是一个用于构建桌面应用程序的用户界面框架。树型结构(TreeView)是WinForm中常见的一种控件,它用于显示层次化的数据,通常表现为节点和子节点的形式,类似于计算机文件系统的目录结构。对于...

    关于java树型结构

    这种非线性的数据结构在处理层次关系的问题时非常有用,如文件系统、组织结构、网页链接等。 在Java中,树型结构主要由两种类型实现:二叉树和多叉树。二叉树是最简单的一种,每个节点最多有两个子节点,分为左子...

    生成JSON树型表结构

    2. 构建树型数据:在后台处理中,可以通过SQL查询语句获取到层级关系的数据,然后将其转化为上述JSON格式。这通常涉及到递归操作,确保所有层级都被正确地表示出来。 3. 传递数据给EXT树:在前端,我们需要创建一个...

    易语言源码树型框读出EDB数据库.rar

    易语言源码树型框读出EDB数据库.rar 易语言源码树型框读出EDB数据库.rar 易语言源码树型框读出EDB数据库.rar 易语言源码树型框读出EDB数据库.rar 易语言源码树型框读出EDB数据库.rar 易语言源码树型框读出EDB...

    一种基于Ajax的动态树型结构的设计与实现.pdf

    随着Web技术的发展,树型结构在B/S模式(浏览器/服务器模式)中的应用也越来越广泛。 当前,网络上常见的树型结构主要分为两类:静态树型结构和动态树型结构。静态树型结构实现起来较为简单,但不支持动态更新节点...

    JSP实现树型结构TREE

    在IT行业中,构建树型结构的数据展示是一种常见的需求,特别是在Web应用中,用户界面往往需要以层次化的形式展示数据。本例"JSP实现树型结构TREE"提供了一个使用JSP(JavaServer Pages)、EXTJS(一个前端JavaScript...

    基于AJAX技术的动态树型结构的设计与实现.pdf

    在科研管理系统中,基于AJAX技术的动态树型结构可以实现实时更新数据和交互性强的用户界面,提高了系统的响应速度和用户体验。同时,AJAX技术也可以降低服务器的负载,提高系统的可扩展性和可维护性。 本文还对科研...

    实验2-树型结构及其应用1

    在本实验"实验2-树型结构及其应用1"中,我们将探讨树型结构的核心概念,特别是二叉树的建立、遍历以及相关应用。树型结构是计算机科学中一种重要的数据组织方式,广泛应用于软件工程、数据管理、编译器设计等多个...

    使用冗余数据设计树型关系的数据结构.pdf

    由于提供的文件内容未能直接给出关于“使用冗余数据设计树型关系的数据结构”的具体知识点,而是包含了维普资讯的网址和资源达人分享计划的标签,我们无法从中提取到实际的文档内容用于生成知识点。不过,可以基于...

    树型结构的存储文件 VB源码

    在IT领域,树型结构是一种常见的数据组织方式,它模拟了自然界中的树状关系,具有层级分明、易于查找和管理的特点。VB(Visual Basic)是微软公司开发的一种面向对象的编程语言,它提供了丰富的控件和函数库,使得...

    易语言源码易语言设置树型框连线颜色.rar

    易语言源码易语言设置树型框连线颜色.rar 易语言源码易语言设置树型框连线颜色.rar 易语言源码易语言设置树型框连线颜色.rar 易语言源码易语言设置树型框连线颜色.rar 易语言源码易语言设置树型框连线颜色.rar ...

Global site tag (gtag.js) - Google Analytics