转自:http://blog.oracle.com.cn/html/83/t-122083.html
简单的树型结构
关于树的普通应用
学习了下这个函数, 用ORGINDUSTRIES的表做了个测试:
正常的树型结构
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=1
connect by pindid=prior indid
结果显示如下
Indlevel indid pindid
服装与服饰 1 1 0
服装 2 2 1
女装 3 3 2
倒型树
下面这个例子是个”倒数”—倒过来的树型结构
select lpad(' ',6*(level-1))||industry,indlevel,indid,pindid
from ORGINDUSTRIES
start with indid=20
connect by indid=prior pindid;
这是标准结果:
Indlevel indid pindid
二手服装 3 20 2
服装 2 2 1
服装与服饰 1 1 0
结论
无论正树还是倒树, 关键就在于connect by的条件.
正树: 必须是 ‘父’= prior ‘子’
倒树: 必须是 ‘子’= prior ‘父’
树型结构的条件过滤
采用树型结构的话, 如果我们想将树上的一个分支砍掉. 将分支后面的结构都抛弃掉, 这个可以实现麽?当然可以。 但是不是用where, where条件只能去除单一的条件。
所以, 这种树型的过滤条件就需要加在connect by上面。
测试如下:由于用真实环境比较贴近实际,所以提前用下SYS_CONNECT_BY_PATH函数来显示下环境
不加任何条件的环境:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
start with areaname='中国大陆'
connect by parentareaid=prior areaid
结果:
1 中国大陆,中国大陆
2 北京 ,中国大陆,北京
3 北京 ,中国大陆,北京,北京
4 东城区 ,中国大陆,北京,东城区
5 西城区 ,中国大陆,北京,西城区
22 广东 ,中国大陆,广东
23 广州 ,中国大陆,广东,广州
24 汕尾 ,中国大陆,广东,汕尾
25 潮阳 ,中国大陆,广东,潮阳
46 上海 ,中国大陆,上海
47 上海 ,中国大陆,上海,上海
48 黄浦区 ,中国大陆,上海,黄浦区
49 闸北区 ,中国大陆,上海,闸北区
加了where过滤条件的SQL:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid
结果为:
2 北京 ,中国大陆,北京
3 北京 ,中国大陆,北京,北京
4 东城区 ,中国大陆,北京,东城区
5 西城区 ,中国大陆,北京,西城区
22 广东 ,中国大陆,广东
23 广州 ,中国大陆,广东,广州
24 汕尾 ,中国大陆,广东,汕尾
25 潮阳 ,中国大陆,广东,潮阳
46 上海 ,中国大陆,上海
47 上海 ,中国大陆,上海,上海
48 黄浦区 ,中国大陆,上海,黄浦区
49 闸北区 ,中国大陆,上海,闸北区
结论:去掉了“1 中国大陆,中国大陆”数据
加了connect by的过滤条件:
select areaname,sys_connect_by_path(areaname,',')
from areas bb
where bb.areaid>861000
start with areaname='中国大陆'
connect by parentareaid=prior areaid and areaname<>'广东'
结果为:
2 北京 ,中国大陆,北京
3 北京 ,中国大陆,北京,北京
4 东城区 ,中国大陆,北京,东城区
5 西城区 ,中国大陆,北京,西城区
46 上海 ,中国大陆,上海
47 上海 ,中国大陆,上海,上海
48 黄浦区 ,中国大陆,上海,黄浦区
49 闸北区 ,中国大陆,上海,闸北区
结论:去掉了整个广东的分支, 在结果集中只有北京和上海
SYS_CONNECT_BY_PATH函数
采用SYS_CONNECT_BY_PATH函数为:
select industry,sys_connect_by_path(industry,'/')
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;
结果为:
女装 /女装
服装 /女装/服装
服装与服饰 /女装/服装/服装与服饰
这样的话, 就可以实现, 树结构的结果集的单行拼接:
我们只需要取最大的字段就OK了
测试如下:
select max(sys_connect_by_path(industry,'/'))
from ORGINDUSTRIES
start with indid=3
connect by indid=prior pindid;
结果为:
/女装/服装/服装与服饰
复杂的树型结构――多列变单列
树型结构也分单树和多树(我的称呼,实际上就是指单支和多支)
对于下面的这种情况, 我们必须要构造的树就属于单支树。
原始环境
环境如下:
select * from test;
结果为:
1 n1
1 n2
1 n3
1 n4
1 n5
3 t1
3 t2
3 t3
3 t4
3 t5
3 t6
2 m1
造树
脚本如下:
select no,q,
no+row_number() over( order by no) rn,
row_number() over(partition by no order by no) rn1
from test
结果如下:
No Q RN RN1
1 n1 2 1
1 n2 3 2
1 n3 4 3
1 n4 5 4
1 n5 6 5
2 m1 8 1
3 t1 10 1
3 t2 11 2
3 t3 12 3
3 t4 13 4
3 t5 14 5
3 t6 15 6
每列的目的是:
RN1列主要的目的是分组, 按照value值‘1’,我们可以start with使用它。
RN列主要用来做connect by使用。 实际上它就是我们要的树。
第一个支: 2,3,4,5,6
第二个支: 8
第三个支: 10,11,12,13,14,15
中间为什么要断掉:7,9 目的就是为了区别每个分支。 到后面看具体的SQL,就明白这里的说法了。
杀手锏
既然我们有了树, 就可以使用树型函数SYS_CONNECT_BY_PATH和connect by啦,来拼接我们所需要的多列值。
脚本如下:
select no,sys_connect_by_path(q,',')
from (
select no,q,
no+row_number() over( order by no) rn,
row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn
结果为:
1 ,n1
1 ,n1,n2
1 ,n1,n2,n3
1 ,n1,n2,n3,n4
1 ,n1,n2,n3,n4,n5
2 ,m1
3 ,t1
3 ,t1,t2
3 ,t1,t2,t3
3 ,t1,t2,t3,t4
3 ,t1,t2,t3,t4,t5
3 ,t1,t2,t3,t4,t5,t6
终极武器
最终我们要的值,是单列值, 其实想想, 也就是最长的一行咯。 那么就好办了。 我们直接GROUP BY ,然后取MAX值。
脚本如下:
select no,max(sys_connect_by_path(q,','))
from (
select no,q,
no+row_number() over( order by no) rn,
row_number() over(partition by no order by no) rn1
from test
)
start with rn1=1
connect by rn-1=prior rn
group by no
结果为:
1 ,n1,n2,n3,n4,n5
2 ,m1
3 ,t1,t2,t3,t4,t5,t6
如果觉得前面的‘,’不好看,可以使用ltrim去掉。 或者用substr也可以。
如下:
ltrim(max(sys_connect_by_path(q,',')),',')
或者
substr(max(sys_connect_by_path(q,',')),2)
分享到:
相关推荐
静态树型结构实现起来较为简单,但不支持动态更新节点信息。相比之下,动态树型结构虽然能够实时添加、修改或删除节点,但在传统的实现方式中,往往需要频繁刷新页面,这不仅增加了服务器的负担,也降低了用户体验。...
本篇文章将深入探讨如何在HTML环境下利用JavaScript实现简单且实用的树型结构,并扩展到与其他服务器端技术如JSP、ASP、PHP的结合。 首先,创建树型结构的基本元素是HTML的`<ul>`和`<li>`标签。`<ul>`代表无序列表...
下面将详细阐述如何使用这三种技术来实现树型结构。 一、HTML基础 HTML(HyperText Markup Language)主要用于构建网页的基本结构。在创建树型结构时,我们通常使用`<ul>`和`<li>`元素来代表树的节点和子节点。例如...
在IT行业中,构建树型结构的数据展示是一种常见的需求,特别是在Web应用中,用户界面往往需要以层次化的形式展示数据。本例"JSP实现树型结构TREE"提供了一个使用JSP(JavaServer Pages)、EXTJS(一个前端JavaScript...
本篇将深入探讨如何利用JavaScript实现这样的功能,结合简单、易用且美观的代码示例,帮助解决你关于创建类似Windows文件夹结构的树型结构的困扰。 首先,理解树型结构的基本概念是关键。树形结构是一种数据结构,...
在IT领域,树型结构是一种重要的数据结构,它在计算机科学中扮演着核心角色,尤其在算法和数据存储方面。树形结构模拟了自然界中的层级关系,非常适合表示具有层次性的数据,例如文件系统、组织结构、网页链接等。在...
dTree是一种简单易用的JavaScript脚本,通过定义一些基本参数即可构建出树型结构目录。具体步骤如下: 1. **初始化菜单**:首先需要定义树的结构,例如使用数组来表示节点及其父节点的关系。 ```javascript var ...
在这个上下文中,"MFC树型结构图"指的是MFC框架中关于树控件(CTreeCtrl)的使用和实现。 在MFC中,树型结构图常用于展现层次化的数据,比如文件系统目录结构。CTreeCtrl类提供了创建、管理这种结构的功能。下面将...
"自动生成树型结构,易懂"这个标题暗示了我们将会探讨一种简单的方法来创建这样的结构,利用HTML、JavaScript和CSS这三种基本的Web技术。"checktree"标签可能是指具有复选框功能的树形控件,常用于导航菜单或者多级...
在这个主题中,我们将深入探讨树型结构的基本概念、如何用JS实现以及`RTree-1.4.3`库的相关应用。 1. **树型结构基本概念** - **节点(Node)**:树的基本组成单元,每个节点可以包含数据和子节点。 - **根节点...
创建一个基本的树型结构非常简单。以下是一个示例代码: ```javascript Ext.create('Ext.tree.Panel', { renderTo: Ext.getBody(), title: 'Simple Tree', width: 150, height: 150, root: { text: 'Root', ...
基本要求:利用树型结构设计并实现一个简单的目录管理系统。功能主要包括: (1)系统可以对所有目录进行管理,类似C盘、D盘、E盘; (2)实现子目录和文件的新建、删除、查询、子目录和文件名称修改等功能; (3)按某种...
在IT领域,特别是Java编程中,树型结构是一种非常重要的数据结构。它模拟了自然界中的树状模型,其中每个节点可以有零个或多个子节点,而根节点没有父节点。这种非线性的数据结构在处理层次关系的问题时非常有用,如...
在JavaScript中,生成树型结构是一项常见的任务,特别是在构建数据可视化、文件系统或者组织复杂的DOM结构时。树型结构是一种数据结构,它由节点(或称为元素)组成,每个节点可以有零个或多个子节点,形成一种层次...
一种基于树型结构的BS系统权限控制方法,是IT领域内一种创新的权限管理策略,尤其适用于基于浏览器/服务器(B/S)架构的信息系统。这种方法不仅优化了传统的基于角色的访问控制(RBAC)技术,还针对Web信息系统中...
下面我们将深入探讨如何使用Java实现`TreeView`树型结构组件,并结合源代码进行解析。 首先,`JTree`类是Java Swing中的一个核心组件,它是`javax.swing.JComponent`的子类。通过`JTree`,我们可以创建具有可展开/...
利用树型结构设计并实现一个简单的目录管理系统,该系统可以对所有目录进行管理,如目录的新建、删除、查询、目录名称修改、按某种顺序输出所有目录(树的遍历操作)、以树型结构输出所有目录等功能。
在网页开发中,构建树型结构是一种常见的需求,例如用于展示目录层级、组织结构或数据分类等。本示例利用JavaScript(简称js)、HTML的div和span元素来实现这一功能,这种方法简单易懂,便于自定义和扩展。下面将...
树型结构是一类重要的非线性数据结构,而二叉树是最为重要,最为常用的类型。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可以用树来形象表示。树在计算机领域中也得到广泛应用,如在编译程序...