oracle分层查询中的start with和connect by(树

系统 2175 0
来源:  http://blog.csdn.net/itmyhome1990/article/details/16338637
 
ORACLE是一个关系数据库管理系统,它用表的形式组织数据,在某些表中的数据还呈现出树型 结构的联系。
 例如有如下案例:
oracle分层查询中的start with和connect by(树结构查询)

数据为节选,字段值含义分别为 税务机构代码、税务机构名称、上级税务机构代码,税务机构级别
select * from extern_dm_swjg查询的时候默认顺序就是上面的顺序,可以看出是混乱的并没有特殊结构特征。

而希望的结果如下图:
oracle分层查询中的start with和connect by(树结构查询)
sj_swjg_dm为空即根节点的排在第一个,仔细观察 上图是树结构查询结果,可能不太直观,看下图就清楚了
oracle分层查询中的start with和connect by(树结构查询)

1. 树结构的描述 
树结构的数据存放在表中,数据之间的层次关系即父子关系,通过表中的列与列间的关系来描述,
通过每个节点的父节点,就可以确定整个树结构。
在SELECT命令中使用CONNECT BY和START WITH 子句可以查询表中的树型结构关系。其命令格式如下:
SELECT ... 
CONNECT BY {PRIOR 列名1=列名2|列名1=PRIOR 列名2} 
[START WITH]... 
其中: CONNECT BY子句说明每行数据将是按层次顺序检索 ,并规定将表中的数据连入树型结构的关系中。PRIORY运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR运算符在的一侧表示父节点,在另一侧表示子节点, 从而确定查找树结构是的顺序是自顶向下还是自底向上
START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。

例1 以树结构方式显示表的数据。
  1. select swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. connect  by  prior swjg_dm = sj_swjg_dm  
  4. start  with sj_swjg_dm  is  null  

2. 关于PRIOR 
运算符PRIOR被放置于等号前后的位置,决定着查询时的检索顺序。

例2从节点开始自底向上查询
  1. select swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. connect  by  swjg_dm =   prior sj_swjg_dm  
  4. start  with swjg_dm =  '16107100004'  

3.使用LEVEL 
    在具有树结构的表中,每一行数据都是树结构中的一个节点,由于节点所处的层次位置不同,所以每行记录都可以有一个层号。层号根据节点与根节点的距离确定。不论从哪个节点开始,该起始根节点的层号始终为1,根节点的子节点为2, 依此类推。 
    在查询中,可以使用伪列LEVEL显示每行数据的有关层次。LEVEL将返回树型结构中当前节点的层次,我们可以使用LEVEL来控制对树型结构进行遍历的深度。
 
例3 显示表中的各行数据及层号。
  1. select  level, swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. connect  by  prior swjg_dm = sj_swjg_dm  
  4. start  with sj_swjg_dm  is  null  

伪列LEVEL为数值型,可以在SELECT 命令中用于各种计算。 

例4 使用LEVEL改变查询结果的显示形式。
  1. select LPAD( LEVEL, LEVEL*3, ' ')  as  "LEVEL", swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. connect  by  prior swjg_dm = sj_swjg_dm  
  4. start  with sj_swjg_dm  is  null   

在SELECT使用了函数LPAD,关于LPAD函数的使用,请参阅 Oracal的Lpad函数
4.节点和分支的裁剪 
    在对树结构进行查询时,可以去掉表中的某些行,也可以剪掉树中的一个分支,使用WHERE子句来限定树型结构中的单个节点,以去掉树中的单个节点,但它却不影响其后代节点(自顶向下检索时)或前辈节点(自底向顶检索时)。

例5  仅剪去了树中单个节点16107100003 扶风县国家税务局
  1. select LPAD( LEVEL, LEVEL*3, ' ')  as  "LEVEL", swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. where swjg_dm != '16107100003'  
  4. connect  by  prior swjg_dm = sj_swjg_dm  
  5. start  with sj_swjg_dm  is  null  
oracle分层查询中的start with和connect by(树结构查询)
 在这个查询中,仅剪去了树中单个节点swjg_dm为16107100003的,可它的子节点依然存在。若希望剪去树结构中的某个分支,
 则要用CONNECT BY 子句。CONNECT BY 子句是限定树型结构中的整个分支,既要剪除分支上的单个节点,
 也要剪除其后代节点(自顶向下检索时)或前辈节点(自底向顶检索时)。

例6  除去节点16107100003的一支
  1. select LPAD( LEVEL, LEVEL*3, ' ')  as  "LEVEL", swjg_dm,swjg_mc,sj_swjg_dm,swjg_level  
  2. from extern_dm_swjg  
  3. connect  by  prior swjg_dm = sj_swjg_dm  
  4. and swjg_dm != '16107100003'  
  5. start  with sj_swjg_dm  is  null  
oracle分层查询中的start with和connect by(树结构查询)
    这个查询结果就与例5不同,除了剪去单个节点 16107100003 外,还将 16107100003 的子节点16107100004剪掉,即把 16107100003  这个分支剪掉了。 
    当然WHERE子句可以和CONNECT BY子句联合使用,这样能够同时剪掉单个节点和树中的某个分支。
 
在使用SELECT 语句来报告树结构报表时应当注意,CONNECT BY子句不能作用于出现在WHERE子句中的表连接。如果需要进行连接,可以先用树结构建立一个视图,再将这个视图与其他表连接,以完成所需要的查询。

oracle分层查询中的start with和connect by(树结构查询)


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论