oracle 递归层次查询

工作需要,要查询一个节点的所有子节点信息,在网上找了很久,没有看到直接的例子的,很多理论,所以给个例子,作为我这种小白水平的人看看:

举例子:

create table SCAN_MERC_INFO
(
  com_merc_id          VARCHAR2(32) not null, //当前节点
 
  superior_com_merc_id VARCHAR2(32),//父节点

)

--ok  根节点向子节点查
selectcom_merc_id,superior_com_merc_id from scan_merc_info
start with com_merc_id = 'qr8'  //这里也可以查询多个节点的,用or 或者是in都可以

connect by prior com_merc_id = superior_com_merc_id


--ok  子节点向根节点查
select merc_id,com_merc_id,superior_com_merc_id,self_level from scan_merc_info
start with com_merc_id = 'qr8'
connect by PRIOR  superior_com_merc_id = com_merc_id 


--取得该节点的所有父节点和所有子节点
select com_merc_id          from scan_merc_info
start with com_merc_id = 'qr8'
connect by PRIOR  superior_com_merc_id = com_merc_id 
union

select com_merc_idfrom scan_merc_info

start with com_merc_id = 'qr8'
connect by PRIOR com_merc_id = superior_com_merc_id


理论来袭:

CONNECT BY 子句说明每行数据将是按层次顺序检索,并规定将表中的数据连入树型结构的关系中。PRIORY 运算符必须放置在连接关系的两列中某一个的前面。对于节点间的父子关系,PRIOR 运算符所在的列表示该列是父节点,相应的另一列则表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。在连接关系中,除了可以使用列名外,还允许使用列表达式。START WITH 子句为可选项,用来标识哪个节点作为查找树型结构的根节点。若该子句被省略,则表示所有满足查询条件的行作为根节点。 

START WITH选项:不但可以指定一个根节点,还可以指定多个根节点。 

http://blog.csdn.net/nsj820/article/details/6299276

语法格式:

select [level], column, expr... from table
[where condition]
start with condition
connect by [prior column1= column2 |
column1 = prior column2];

层次查询是通过start with和connect by子句标识的:

1.其中level关键字是可选的,表示等级,1表示root,2表示root的child,其他相同的规则。

2.From之后可以是table,view但是只能是一个table

3.Where条件限制了查询返回的行,但是不影响层次关系,属于将节点截断,但是这个被截断的节点的下层child不受影响。

4.Start with是表示开始节点,对于一个真实的层次关系,必须要有这个子句,但是不是必须的。

5.connect by prior是指定父子关系,其中prior的位置不一定要在connect by之后,对于一个真实的层次关系,这也是必须的。

对于from是视图的,那么这个view不能包含join

层次查询限制

1.层次查询from 之后如果是table,只能是一个table,不能有join。

2.from之后如果是view,则view不能是带join的。

3.使用order by子句,order子句是在等级层次做完之后开始的,所以对于层次查询来说没有什么意义,除非特别关注level,获得某行在层次中的深度,但是这两种都会破坏层次。见增强特性中的使用siblings排序。

4.在start with中表达式可以有子查询,但是connect by中不能有子查询。

层次查询的增强特性

1、SYS_CONNECT_BY_PATH

Oracle 9i提供了sys_connect_by_path(column,char),其中column是字符型或能自动转换成字符型的列名。它的主要目的就是将父节点到当前节点的”path”按照指定的模式展现出现。这个函数只能使用在层次查询中。

下面的是oracle10g新增特性

2、 CONNECT_BY_ISLEAF

    在oracle9i的时候,查找指定root下的叶子节点,是很复杂的,oracle10g引入了一个新的函数,connect_by_isleaf,如果行的值为0表示不是叶子节点,1表示是叶子节点。

3、CONNECT_BY_ISCYCLE和NOCYCLE关键字

    如果从root节点开始找其子孙,找到一行,结果发生和祖先互为子孙的情况,则发生循环,oracle会报ORA-01436: CONNECT BY loop in user data,在9i中只能将发生死循环的不加入到树中或删除,在10g中可以用nocycle关键字加在connect by之后,避免循环的参加查询操作。并且通过connect_by_iscycle得到哪个节点发生循环。0表示未发生循环,1表示发生了循环。

4、CONNECT_BY_ROOT

    Oracle10g新增connect_by_root,用在列名之前表示此行的根节点的相同列名的值。

5、使用SIBLINGS关键字排序

    对于层次查询如果用order by排序,比如order by last_name则是先做完层次获得level,然后按last_name排序,这样破坏了层次,比如特别关注某行的深度,按level排序,也是会破坏层次的。

     在oracle10g中,增加了siblings关键字的排序。

语法:order  siblings  by <expre>

它会保护层次,并且在每个等级中按expre排序。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值