ORACLE层次查询学习

前端之家收集整理的这篇文章主要介绍了ORACLE层次查询学习前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

层次查询的概念

语法格式:

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关键字的排序。

语法:ordersiblingsby <expre>

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

示例:

1、构建测试表与插入测试语句

[c-sharp] view plain copy print ?
  1. createtabletab_connect_by(childnumber,parentnumber);
  2. insertintotab_connect_by(CHILD,PARENT)values(2,5);
  3. insertintotab_connect_by(CHILD,PARENT)values(3,5);
  4. insertintotab_connect_by(CHILD,PARENT)values(10,15);
  5. insertintotab_connect_by(CHILD,PARENT)values(5,15);
  6. insertintotab_connect_by(CHILD,PARENT)values(9,17);
  7. insertintotab_connect_by(CHILD,PARENT)values(8,17);
  8. insertintotab_connect_by(CHILD,PARENT)values(15,38);
  9. insertintotab_connect_by(CHILD,PARENT)values(17,38);
  10. insertintotab_connect_by(CHILD,PARENT)values(6,PARENT)values(13,26);
  11. insertintotab_connect_by(CHILD,PARENT)values(1,26);
  12. insertintotab_connect_by(CHILD,PARENT)values(12,PARENT)values(11,18);
  13. insertintotab_connect_by(CHILD,PARENT)values(7,18);
  14. insertintotab_connect_by(CHILD,PARENT)values(38,null);
  15. insertintotab_connect_by(CHILD,PARENT)values(26,153)">null);
  16. insertintotab_connect_by(CHILD,PARENT)values(18,153)">null);
  17. commit;

2、查询语句1

  • selecta.child,
  • a.parent,
  • level"层次",
  • sys_connect_by_path(child,'<-')"合并层次",
  • priora.child"父节点",
  • connect_by_roota.child"根节点",
  • decode(connect_by_isleaf,1,a.child,153)">null)"子节点",
  • decode(connect_by_isleaf,'是','否')"是否子节点"
  • fromtab_connect_bya
  • startwitha.parentisnull--从parent为空开始扫描
  • connectbypriora.child=a.parent--以child为父列连接parent
  • ordersiblingsbychilddesc--对层次排序
  • ;
  • 3、查询语句2

  • Selectlevel,connect_by_iscycle,connect_by_isleaf,parent,child
  •   Fromtab_connect_by
  •   Connectbynocyclepriorchild=parent
  •   Startwithparentnull;
  • 猜你在找的Oracle相关文章