`
czjxdm
  • 浏览: 124699 次
社区版块
存档分类
最新评论

简单的树型结构

阅读更多
转自: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)
分享到:
评论

相关推荐

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

    静态树型结构实现起来较为简单,但不支持动态更新节点信息。相比之下,动态树型结构虽然能够实时添加、修改或删除节点,但在传统的实现方式中,往往需要频繁刷新页面,这不仅增加了服务器的负担,也降低了用户体验。...

    简单js树型结构好用

    本篇文章将深入探讨如何在HTML环境下利用JavaScript实现简单且实用的树型结构,并扩展到与其他服务器端技术如JSP、ASP、PHP的结合。 首先,创建树型结构的基本元素是HTML的`&lt;ul&gt;`和`&lt;li&gt;`标签。`&lt;ul&gt;`代表无序列表...

    树型结构(javascript+css+html)

    下面将详细阐述如何使用这三种技术来实现树型结构。 一、HTML基础 HTML(HyperText Markup Language)主要用于构建网页的基本结构。在创建树型结构时,我们通常使用`&lt;ul&gt;`和`&lt;li&gt;`元素来代表树的节点和子节点。例如...

    JSP实现树型结构TREE

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

    JS生成树型结构

    本篇将深入探讨如何利用JavaScript实现这样的功能,结合简单、易用且美观的代码示例,帮助解决你关于创建类似Windows文件夹结构的树型结构的困扰。 首先,理解树型结构的基本概念是关键。树形结构是一种数据结构,...

    我的树型结构练习使用

    在IT领域,树型结构是一种重要的数据结构,它在计算机科学中扮演着核心角色,尤其在算法和数据存储方面。树形结构模拟了自然界中的层级关系,非常适合表示具有层次性的数据,例如文件系统、组织结构、网页链接等。在...

    基于Ajax技术的树型结构目录的实现

    dTree是一种简单易用的JavaScript脚本,通过定义一些基本参数即可构建出树型结构目录。具体步骤如下: 1. **初始化菜单**:首先需要定义树的结构,例如使用数组来表示节点及其父节点的关系。 ```javascript var ...

    MFC树型结构图

    在这个上下文中,"MFC树型结构图"指的是MFC框架中关于树控件(CTreeCtrl)的使用和实现。 在MFC中,树型结构图常用于展现层次化的数据,比如文件系统目录结构。CTreeCtrl类提供了创建、管理这种结构的功能。下面将...

    自动生成树型结构,易懂

    "自动生成树型结构,易懂"这个标题暗示了我们将会探讨一种简单的方法来创建这样的结构,利用HTML、JavaScript和CSS这三种基本的Web技术。"checktree"标签可能是指具有复选框功能的树形控件,常用于导航菜单或者多级...

    非常实用的树型结构JS代码

    在这个主题中,我们将深入探讨树型结构的基本概念、如何用JS实现以及`RTree-1.4.3`库的相关应用。 1. **树型结构基本概念** - **节点(Node)**:树的基本组成单元,每个节点可以包含数据和子节点。 - **根节点...

    4.0Ext 树型结构

    创建一个基本的树型结构非常简单。以下是一个示例代码: ```javascript Ext.create('Ext.tree.Panel', { renderTo: Ext.getBody(), title: 'Simple Tree', width: 150, height: 150, root: { text: 'Root', ...

    文件目录管理系统.cpp

    基本要求:利用树型结构设计并实现一个简单的目录管理系统。功能主要包括: (1)系统可以对所有目录进行管理,类似C盘、D盘、E盘; (2)实现子目录和文件的新建、删除、查询、子目录和文件名称修改等功能; (3)按某种...

    关于java树型结构

    在IT领域,特别是Java编程中,树型结构是一种非常重要的数据结构。它模拟了自然界中的树状模型,其中每个节点可以有零个或多个子节点,而根节点没有父节点。这种非线性的数据结构在处理层次关系的问题时非常有用,如...

    javascript生成树型结构

    在JavaScript中,生成树型结构是一项常见的任务,特别是在构建数据可视化、文件系统或者组织复杂的DOM结构时。树型结构是一种数据结构,它由节点(或称为元素)组成,每个节点可以有零个或多个子节点,形成一种层次...

    一种基于树型结构的BS系统权限控制方法

    一种基于树型结构的BS系统权限控制方法,是IT领域内一种创新的权限管理策略,尤其适用于基于浏览器/服务器(B/S)架构的信息系统。这种方法不仅优化了传统的基于角色的访问控制(RBAC)技术,还针对Web信息系统中...

    java实现TreeView树型结构组件-源代码

    下面我们将深入探讨如何使用Java实现`TreeView`树型结构组件,并结合源代码进行解析。 首先,`JTree`类是Java Swing中的一个核心组件,它是`javax.swing.JComponent`的子类。通过`JTree`,我们可以创建具有可展开/...

    简单的目录管理系统的设计与应用

    利用树型结构设计并实现一个简单的目录管理系统,该系统可以对所有目录进行管理,如目录的新建、删除、查询、目录名称修改、按某种顺序输出所有目录(树的遍历操作)、以树型结构输出所有目录等功能。

    js+div+span实现树型结构

    在网页开发中,构建树型结构是一种常见的需求,例如用于展示目录层级、组织结构或数据分类等。本示例利用JavaScript(简称js)、HTML的div和span元素来实现这一功能,这种方法简单易懂,便于自定义和扩展。下面将...

    erchashu.rar_二叉树_二叉树遍历_完全遍历_树型结构_树结构

    树型结构是一类重要的非线性数据结构,而二叉树是最为重要,最为常用的类型。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可以用树来形象表示。树在计算机领域中也得到广泛应用,如在编译程序...

Global site tag (gtag.js) - Google Analytics