ITPub博客

首页 > Linux操作系统 > Linux操作系统 > connect by 各种用法总结

connect by 各种用法总结

原创 Linux操作系统 作者:dregs_zb 时间:2008-07-18 16:29:05 0 删除 编辑

今天事情不是很多,就小结了一下树形查询start with .. . connect by ...的各种用法。 下面以个例子展开。 SQL>create table test_connect_by (child number,parent number); insert into TEST_CONNECT_BY (CHILD, PARENT) values (2, 5); insert into TEST_CONNECT_BY (CHILD, PARENT) values (3, 5); insert into TEST_CONNECT_BY (CHILD, PARENT) values (10, 15); insert into TEST_CONNECT_BY (CHILD, PARENT) values (5, 15); insert into TEST_CONNECT_BY (CHILD, PARENT) values (9, 17); insert into TEST_CONNECT_BY (CHILD, PARENT) values (8, 17); insert into TEST_CONNECT_BY (CHILD, PARENT) values (15, 38); insert into TEST_CONNECT_BY (CHILD, PARENT) values (17, 38); insert into TEST_CONNECT_BY (CHILD, PARENT) values (6, 38); insert into TEST_CONNECT_BY (CHILD, PARENT) values (13, 26); insert into TEST_CONNECT_BY (CHILD, PARENT) values (1, 26); insert into TEST_CONNECT_BY (CHILD, PARENT) values (12, 26); insert into TEST_CONNECT_BY (CHILD, PARENT) values (11, 18); insert into TEST_CONNECT_BY (CHILD, PARENT) values (7, 18); insert into TEST_CONNECT_BY (CHILD, PARENT) values (38, null); insert into TEST_CONNECT_BY (CHILD, PARENT) values (26, null); insert into TEST_CONNECT_BY (CHILD, PARENT) values (18, null); commit; 1)常规的查询(start with .. connect by prior..) SQL> select child from test_connect_by 2 start with parent is null 3 connect by prior child=parent; CHILD ---------- 38 15 10 5 2 3 17 9 8 6 26 13 1 12 18 11 7 17 rows selected 这样的层次不分明,要利用level. SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent; CHILD -------------------------------------------------------------------------------- 38 15 10 5 2 3 17 9 8 6 26 13 1 12 18 11 7 17 rows selected 当然也可以写成: SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by parent=prior child; CHILD -------------------------------------------------------------------------------- 38 15 10 5 2 3 17 9 8 6 26 13 1 12 18 11 7 17 rows selected prior在 '='左右都可以,只要记住prior那边的列作为父列,另一边的列作为子列就行了。例如刚才的例子: SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by parent=prior child; 和 SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent; 都是以child作为父列去找到相关的记录,所以两个语句的查询结果是一样的。如果以parent作为父列,那结果明显不一样了。 SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by prior parent=child; CHILD -------------------------------------------------------------------------------- 18 26 38 这样查询出来的就只有一层,这样的数据好像没什么现实意义,一般情况应该是树型数据要显示为从leaf到root这样的显示才会以parent作为父列。例如从叶子2开始查询: SQL> select lpad(' ',4*(level-1))||child 2 from test_connect_by 3 start with child=2 4 connect by prior parent=child; LPAD('',4*(LEVEL-1))||CHILD -------------------------------------------------------------------------------- 2 5 15 38

2)筛选某个结点或分支,如果是筛选某个结点不显示则在添加where+条件,如果是筛选分支,则在connect by后面加条件。 例如筛选child为5的结点不显示: SQL> select lpad(' ',4*(level-1))||child child 2 2 from test_connect_by 3 where child!=5 4 start with parent is null 5 connect by prior child=parent; CHILD -------------------------------------------------------------------------------- 38 15 10 2 3 17 9 8 6 26 13 1 12 18 11 7 16 rows selected 如果是筛选child为5这个树枝都不显示,则是: SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent 5 and child!=5; CHILD -------------------------------------------------------------------------------- 38 15 10 17 9 8 6 26 13 1 12 18 11 7 14 rows selected

3)prior+column,这个是显示某个结点的直接父结点,例如: SQL> select level,lpad(' ',4*(level-1))||child child,prior child "parent" 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent; LEVEL CHILD parent ---------- -------------------------------------------------------------------------------- ---------- 1 38 2 15 38 3 10 15 3 5 15 4 2 5 4 3 5 2 17 38 3 9 17 3 8 17 2 6 38 1 26 2 13 26 2 1 26 2 12 26 1 18 2 11 18 2 7 18 17 rows selected

4)sys_connect_by_path 显示父结点到当前结点的路径,例如: SQL> select lpad(' ',4*(level-1))||child child,sys_connect_by_path(child,'|') path 2 from test_connect_by 3 3 start with parent is null 4 connect by prior child=parent; CHILD PATH -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- 38 |38 15 |38|15 10 |38|15|10 5 |38|15|5 2 |38|15|5|2 3 |38|15|5|3 17 |38|17 9 |38|17|9 8 |38|17|8 6 |38|6 26 |26 13 |26|13 1 |26|1 12 |26|12 18 |18 11 |18|11 7 |18|7 17 rows selected 5)connect_by_root 显示结点的根结点,例如: SQL> select lpad(' ',4*(level-1))||child child,connect_by_root child "root" 2 from test_connect_by 3 3 start with parent is null 4 connect by prior child=parent; CHILD root -------------------------------------------------------------------------------- ---------- 38 38 15 38 10 38 5 38 2 38 3 38 17 38 9 38 8 38 6 38 26 26 13 26 1 26 12 26 18 18 11 18 7 18 17 rows selected

6) connect_by_isleaf 判断当前结点是否是叶子,如是则值为1,否则为0.例如: SQL> select lpad(' ',4*(level-1))||child child,connect_by_isleaf "isleaf" 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent; CHILD isleaf -------------------------------------------------------------------------------- ---------- 38 0 15 0 10 1 5 0 2 1 3 1 17 0 9 1 8 1 6 1 26 0 13 1 1 1 12 1 18 0 11 1 7 1 17 rows selected

在这里要注意个问题,当要筛选level的时候,条件的位置不同则结果是不一样的。请看下面两个例子: SQL> select level,lpad(' ',4*(level-1))||child,connect_by_isleaf "isleaf" 2 from test_connect_by 3 start with parent is null 4 connect by prior child=parent and level<=3; LEVEL LPAD('',4*(LEVEL-1))||CHILD isleaf ---------- -------------------------------------------------------------------------------- ---------- 1 38 0 2 15 0 3 10 1 3 5 1 2 17 0 3 9 1 3 8 1 2 6 1 1 26 0 2 13 1 2 1 1 2 12 1 1 18 0 2 11 1 2 7 1 15 rows selected 这个结果很正常,所有叶子结点的isleaf都是为1。 再看下面的例子: SQL> select level,lpad(' ',4*(level-1))||child,connect_by_isleaf "isleaf" 2 from test_connect_by 3 where level<=3 4 start with parent is null 5 connect by prior child=parent; LEVEL LPAD('',4*(LEVEL-1))||CHILD isleaf ---------- -------------------------------------------------------------------------------- ---------- 1 38 0 2 15 0 3 10 1 3 5 0 2 17 0 3 9 1 3 8 1 2 6 1 1 26 0 2 13 1 2 1 1 2 12 1 1 18 0 2 11 1 2 7 1 15 rows selected 有没有发现5好像是叶子结点呀,为什么isleaf是0呢?原因是该语句判断一个结点是否是叶子是根据 SQL> select level,lpad(' ',4*(level-1))||child,connect_by_isleaf "isleaf" 2 from test_connect_by 3 start with parent is null 4connect by prior child=parent; 所生成的树型来作判断的,而不是根据level<=3筛选出的树结构来作判断的。 7)order siblings by 用这个语句来对树形数据来不会改变原来的树结构,只是根据是ASC或是DESC来调整下结构的位置而已。 SQL> select lpad(' ',4*(level-1))||child "child" 2 from test_connect_by 3 3 start with parent is null 4 connect by prior child=parent 5 order siblings by child 6 desc; child -------------------------------------------------------------------------------- 38 17 9 8 15 10 5 3 2 6 26 13 12 1 18 11 7 17 rows selected 如果是用order by 的话则原来的结构就会被打乱了。 SQL> select lpad(' ',4*(level-1))||child child 2 from test_connect_by 3 connect by prior child=parent 4 start with parent is null 5 order by child; CHILD -------------------------------------------------------------------------------- 2 3 10 5 8 9 1 11 12 13 15 17 6 7 18 26 38 17 rows selected

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/8030006/viewspace-404398/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: 没有了~
请登录后发表评论 登录
全部评论

注册时间:2008-05-06

  • 博文量
    3
  • 访问量
    2487