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

简单的树型结构

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

相关推荐

    简单js树型结构好用

    简单树型结构 js 用html .可以做任何动态页面(jsp asp php)

    JS生成树型结构

    非常不错的js代码 简单 易用 而且美观 如果你还对js生成像windows文件夹结构的树型结构苦恼的话 就来下载吧

    论文研究-一种基于树型结构的P2P系统高维数据检索方法.pdf

    针对这些问题,提出一种将树型结构——Baton树应用于高维数据检索的方法,操作简单,无须降维,且支持范围查询。经过实验证明,查询的时间复杂度达到O(log2n),与Baton树在检索一维数据时的效率相同。树型结构可以...

    文件目录管理系统.cpp

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

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

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

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

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

    基于iview的树型结构,使用html页面中引入vue构建树

    Tree树形组件是 iview 中相对复杂的一个组件。 自定义节点内容 使用强大的 Render 函数可以自定义节点显示内容和交互,比如添加...这个demo是几个较为简单的示例,主要记录一下普通的html怎么结合iview的树型组件。。

    js+div+span实现树型结构

    使用js+div+span实现树型结构 非常简单的代码 一看就懂 下载解压直接打开就可以看出效果

    C#实现树型结构TreeView节点拖拽的简单功能,附全部源码,供有需要的参考

    C_实现树型结构TreeView节点拖拽的简单功能,附全部源码,供有需要的参考

    推荐一个树型结构的菜单

    很不错的一个树型菜单,简单易懂,灵活方便

    jquery树型

    jquery树型结构,jqeury简单例子

    Ajax无限极分类树型结构源码

    Ajax无限级树源码 Ajax打造仿WINDWS无限级菜单...简单的模拟Windows文件夹的AJAX无限级菜单树,希望下载后对大家有点用处。 开发环境:VS2005、C#、.net2.0、Access、AJAX 运行环境:IE 绝对强大啊……无可厚非啊……

    文件管理系统

    树型结构,目录下可以是目录,可以是文件。 在此文件管理系统,可实现的操作有: 改变目录:格式:cd &lt;目录名&gt; 显示目录:格式:dir[&lt;目录名&gt;] 创建目录:格式:md &lt;目录名&gt; 删除目录:格式:rd&lt;目录名&gt; 新建文件:...

    java简单文件管理系统源码

    设计一个文件管理方案,模拟一个...要求目录结构为树型结构,目录下可以是目录,也可以是文件。通过该实验是学生可以深刻理解文件系统的概念、所涉及的基本操作及实现时的主要数据结构。&lt;br&gt;建议用eclipse打开。

    用户树型结构

    多选用户树 android实现简单的多选结构树,勾选父节点全选子节点等功能,可以根据自己需要修改。

    简单的树形结构demo

    简单的jquery树形结构实例,可根据本地项目引用,稍作修改便可使用。

    ComboxTree(C#下拉框是树形结构)

    这是一个C#下拉框是树形结构源码,实现简单。

    目录管理系统(数据结构)

    目录管理系统(数据结构)

    一个js代码实现树结构 tree.js

    树结构在很多地方都会用到的,这是js实现树代码,很实用,测试过了可以用的,没有网上的复杂,很好用, 其中,imgSrc要换成你硬盘里存在的图片路径。然后在你的+号图片的单击事件响应使用topOfList()函数即可,我...

    创建无限极分类树型结构的简单方法

    下面小编就为大家带来一篇创建无限极分类树型结构的简单方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

Global site tag (gtag.js) - Google Analytics