为了更好的查询一个树状结构的表,在Oracle的PL/SQL中提供乐一个诱人的特性——CONNECT BY子句。它大大的方便了我们查找树状表:遍历一棵树、寻找某个分支……,但还是存在一些不足。在Oracle 10G,就对这个特性做了增强。下面就举例说明一下:

CONNECT_BY_ROOT一张表,有多颗子树(根节点为0),现在我想知道每个节点属于哪个子树。举例:铃音目录结构下有多个大分类:中外名曲、流行经典、浪漫舞曲……,每个大类下面又有多个子类,子类下面还可以细分。那现在想要知道每个子类分属哪个大类,或者要统计每个大类下面有多少个子类。
看下面的例子,DIRINDEX分别为1、2、3的就是大分类,其他编号的都是子类或孙子类:
select dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname from t_tonedirlib
start with fatherindex = 0
connect by  fatherindex =  prior dirindex
             DIRINDEX           FATHERINDEX DIRNAME                            
--------------------- ------------------------------------
                    1                     0 中文经典                           
                   52                     1   kkkkkkk                          
                   70                    52     222                            
                   58                    52     sixx                           
                   59                    52     seven                          
                   69                    52     uiouoooo                       
                   55                    52     four                           
                    7                     1   流行风云                         
                    8                     1   影视金曲                         
                 1111                     8     aaa                            
                 1112                     8     bbb                            
                 1113                     8     ccc                            
                    9                     1   古典音乐                         
                   81                     1   小熊之家                         
                  104                    81     龙珠                           
                  105                    81     snoppy                         
                  101                    81     叮当1                          
                  102                    81     龙猫                           
                  103                    81     叮当2                          
                    2                     0 热门流行                           
                   31                     2   有奖活动                         
                   32                     2   相约香格里拉                     
                   50                     2   新浪彩铃                         
                    3                     0 老歌回放                           
                  333                     3   老电影                           
                  335                     3   怀旧金曲                         
26 rows selected

如何统计1、2、3三个大类下有哪些子类,有多少个子类?在9i及以前要做这样的统计十分麻烦。现在10G提供了一个新特性:CONNECT_BY_ROOT, 他的作用就是使结果不是当前的节点ID,而满足查询条件下的根节点的ID。以上面为例,我们需要得到以上结果只需要执行以下语句就可以搞定了:
select CONNECT_BY_ROOT dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname from t_tonedirlib
start with fatherindex = 0
connect by  fatherindex =  prior dirindex
CONNECT_BY_ROOTDIRINDEX   FATHERINDEX RPAD('',2*(LEVEL-1))||DIRNAME    
----------------------- ------------- -----------------------------
                      1                     0 中文经典                         
                      1                     1   kkkkkkk                        
                      1                    52     222                          
                      1                    52     sixx                         
                      1                    52     seven                        
                      1                    52     uiouoooo                     
                      1                    52     four                         
                      1                     1   流行风云                       
                      1                     1   影视金曲                       
                      1                     8     aaa                          
                      1                     8     bbb                          
                      1                     8     ccc                          
                      1                     1   古典音乐                       
                      1                     1   小熊之家                       
                      1                    81     龙珠                         
                      1                    81     snoppy                       
                      1                    81     叮当1                        
                      1                    81     龙猫                         
                      1                    81     叮当2                        
                      2                     0 热门流行                         
                      2                     2   有奖活动                       
                      2                     2   相约香格里拉                   
                      2                     2   新浪彩铃                       
                      3                     0 老歌回放                         
                      3                     3   老电影                         
                      3                     3   怀旧金曲                       
26 rows selected

查出来的结果中,CONNECT_BY_ROOTDIRINDEX就是各个子类(孙子类)所属的大类编号,如果需要统计,就只要执行以下语句马上可以统计出来了:
select rootindex, count('X') from
    (select CONNECT_BY_ROOT dirindex as rootindex
    from t_tonedirlib
    start with fatherindex = 0
    connect by  fatherindex =  prior dirindex) a
group by a.rootindex
ROOTINDEX COUNT('X')
--------- ----------
        1         19
        2          4
        3          3
3 rows selected
CONNECT_BY_ISLEAF    经常有DBA因为要查找树状表中的叶子节点而苦恼。大部分DBA为了解决这个问题就给表增加了一个字段来描述这 个节点是否为叶子节点。但这样做有很大的弊端:需要通代码逻辑来保证这个字段的正确性。
    Oracle 10G中提供了一个新特性——CONNECT_BY_ISLEAF——来解决这个问题了。简单点说,这个属性结果表明当前节点在满足条件的查询结果中是否为叶子节点, 0不是,1是:
select CONNECT_BY_ISLEAF, dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname 
from t_tonedirlib
start with fatherindex = 0
connect by  fatherindex =  prior dirindex
CONNECT_BY_ISLEAF DIRINDEX FATHERINDEX RPAD(' ',2*(LEVEL-1))||dirname
----------------- ---------------- ---------------------------------
                0                     1                     0 中文经典         
                0                    52                     1   kkkkkkk        
                1                    70                    52     222          
                1                    58                    52     sixx         
                1                    59                    52     seven        
                1                    69                    52     uiouoooo     
                1                    55                    52     four         
                1                     7                     1   流行风云       
                0                     8                     1   影视金曲       
                1                  1111                     8     aaa          
                1                  1112                     8     bbb          
                1                  1113                     8     ccc          
                1                     9                     1   古典音乐       
                0                    81                     1   小熊之家       
                1                   104                    81     龙珠         
                1                   105                    81     snoppy       
                1                   101                    81     叮当1        
                1                   102                    81     龙猫         
                1                   103                    81     叮当2        
                0                     2                     0 热门流行         
                1                    31                     2   有奖活动       
                1                    32                     2   相约香格里拉   
                1                    50                     2   新浪彩铃       
                0                     3                     0 老歌回放         
                1                   333                     3   老电影         
                1                   335                     3   怀旧金曲       
26 rows selected
    一看结果,清晰明了!
CONNECT_BY_ISCYCLE       我们的树状属性一般都是在一条记录中记录一个当前节点的ID和这个节点的父ID来实现。但是,一旦数据中出现了循环记录,如两个节点互为对方父节点,系统就会报ORA-01436错误:
insert into t_tonedirlib(dirindex, fatherindex, dirname, status) values (666, 667, '123', 5);
1 row inserted

insert into t_tonedirlib(dirindex, fatherindex, dirname, status) values (667, 666, '456', 5);
1 row inserted

select dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname from t_tonedirlib
start with fatherindex = 666
connect by  fatherindex =  prior dirindex
ORA-01436: 用户数据中的 CONNECT BY 循环

10G中,可以通过加上NOCYCLE关键字避免报错。并且通过CONNECT_BY_ISCYCLE属性就知道哪些节点产生了循环:

select CONNECT_BY_ISCYCLE, dirindex, fatherindex, RPAD(' ', 2*(LEVEL-1)) || dirname
from t_tonedirlib
start with fatherindex = 666
connect by NOCYCLE fatherindex =  prior dirindex
CONNECT_BY_ISCYCLE DIRINDEX FATHERINDEX RPAD(' ',2*(LEVEL-1))||dirname
----------------- ---------------- ---------------------------------
                 0                   667                   666 456             
                 1                   666                   667   123           
2 rows selected

oracle connect by prior 树形结构相关推荐

  1. Oracle递归查询(适合树形结构)

    select *from V_PLACE_DEVICE  START WITH ID=${SELECTID} CONNECT BY PRIOR PARENTID = ID 转载于:https://ww ...

  2. Oracle树形结构查询之prior的理解

    --1 建表 create table 宇宙 ( 行星等级 number ,行星名称 varchar2(50) ,上级行星等级 number ); --2 数据准备 insert into 宇宙 (行 ...

  3. Start with...Connect By子句递归查询一般用于一个表维护树形结构的应用。

    Start with...Connect By子句递归查询一般用于一个表维护树形结构的应用. 创建示例表: CREATE TABLE TBL_TEST (   ID    NUMBER,   NAME ...

  4. oracle 递归查询,Oracle递归查询(start with…connect by prior)

    查询基本结构: select - from table_name start with 条件1 connect by 条件2 1.建测试用表 1 create table test_prior( 2 ...

  5. mysql 查询树形结构_MySql/Oracle树形结构查询

    Oracle树形结构递归查询 在Oracle中,对于树形查询可以使用start with ... connect by select * from treeTable start with id='1 ...

  6. Oracle 树操作(select…start with…connect by…prior)

    oracle树查询的最重要的就是select-start with-connect by-prior语法了.依托于该语法,我们可以将一个表形结构的以树的顺序列出来.在下面列述了oracle中树型查询的 ...

  7. Oracle中start with...connect by prior子句用法

    http://www.cnblogs.com/ZHF/archive/2008/09/10/1288101.html Oracle中start with...connect by prior子句用法 ...

  8. oracle中用START WITH...CONNECT BY PRIOR子句实现递归查询

    今天发现在oracle中的select语句可以用START WITH...CONNECT BY PRIOR子句实现递归查询,connect by 是结构化查询中用到的,其基本语法是: select . ...

  9. oracle中 sql语句:start with .. connect by prior.. 用法

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. 我们经常会将一个比较复杂的目录树存储到一个表中.或者将一些部门存储到一个表中,而这些部门互相有隶属关 ...

最新文章

  1. 【放置奇兵】算法 酒馆攻略
  2. Docker容器的生命周期管理
  3. 【渝粤题库】陕西师范大学700005 遗传学
  4. MeasureSpec学习 - 转
  5. 1071 - Specified key was too long; max key length is 767 bytes
  6. 2019 蓝桥杯省赛 B 组模拟赛(一) J. 程序设计:蒜厂年会 环形连续子序列求和问题
  7. leetcode875.KokoEatingBananas
  8. mysq 没有mysql数据库_mysq 没有mysql数据库
  9. javascript在数组的开头推送元素[重复]
  10. [OpenGL]自己写的加载位图并转换成纹理的两个函数
  11. MEF(Managed Extensibility Framework)学习笔记
  12. 读《财务就是IT 企业财务信息系统》
  13. java 智能一卡通系统_基于Java框架的银医一卡通系统设计
  14. linux鼠标选中的内容不能复制,解决vim不能使用鼠标右键复制的问题
  15. 台式计算机显卡最高温度多少,笔记本/台式机显卡核心多少度正常?GPU温度过高该如何处理?...
  16. python发送邮件 退回_【破案了】python发邮件问题,求助!为什么总被退回?
  17. 支付行业架构流程梳理
  18. 电商用户行为分析-大数据
  19. 帝国cms生成静态php,帝国cms自动生成手机版静态插件
  20. 以太坊Solidity编程中你不知道的单位

热门文章

  1. umeng(友盟)集成
  2. ThinkPad T460进入BIOS的方式
  3. 阿里云备案服务号申请方法及说明
  4. Java程序员除了做增删改查还能干嘛?
  5. 程序员欣宸文章汇总(Java篇)
  6. css和html基础
  7. 威纶通触摸屏如何进入系统设置画面?
  8. python 在命令行中提示 indentationError:expected an indented block
  9. [web安全]常见加密相关算法简介
  10. 6补充:matlab的imread函数用法