connect by

简介: Oracle中connect by...start with...的使用   一、语法  大致写法:select * from some_table [where 条件1] connect by [条件2] start with [条件3];  其中 connect by 与 start with 语句摆放的先后顺序不影响查询的结果,[where 条件1]可以不需要。

Oracleconnect by...start with...的使用

 

一、语法 

大致写法:select * from some_table [where 条件1] connect by [条件2] start with [条件3]; 

其中 connect by 与 start with 语句摆放的先后顺序不影响查询的结果,[where 条件1]可以不需要。 

[where 条件1][条件2][条件3]各自作用的范围都不相同: 

 

[where 条件1]是在根据connect by [条件2] start with [条件3]选择出来的记录中进行过滤,是针对单条记录的过滤, 不会考虑树的结构; 

 

[条件2]指定构造树的条件,以及对树分支的过滤条件,在这里执行的过滤会把符合条件的记录及其下的所有子节点都过滤掉; 

 

[条件3]限定作为搜索起始点的条件,如果是自上而下的搜索则是限定作为根节点的条件,如果是自下而上的搜索则是限定作为叶子节点的条件; 

 

示例: 

假如有如下结构的表:some_table(id,p_id,name),其中p_id保存父记录的id。 

select * from some_table t where t.id!=123 connect by prior t.p_id=t.id and t.p_id!=321 start with t.p_id=33 or t.p_id=66; 

 

prior的说明: 

    prior存在于[条件2]中,可以不要,不要的时候只能查找到符合start with [条件3]的记录,不会在寻找这些记录的子节点。要的时候有两种写法:connect by prior t.p_id=t.id 或 connect by t.p_id=prior t.id,前一种写法表示采用自上而下的搜索方式(先找父节点然后找子节点),后一种写法表示采用自下而上的搜索方式(先找叶子节点然后找父节点)。 

 

二、执行原理 

connect by...start with...的执行原理可以用以下一段程序的执行以及对存储过程RECURSE()的调用来说明: 

 

/* 遍历表中的每条记录,对比是否满足start with后的条件,如果不满足则继续下一条, 

如果满足则以该记录为根节点,然后调用RECURSE()递归寻找该节点下的子节点, 

如此循环直到遍历完整个表的所有记录 。*/ 

for rec in (select * from some_table) loop 

if FULLFILLS_START_WITH_CONDITION(rec) then 

    RECURSE(rec, rec.child); 

end if; 

end loop; 

 

/* 寻找子节点的存储过程*/ 

procedure RECURSE (rec in MATCHES_SELECT_STMT, new_parent IN field_type) is 

begin 

APPEND_RESULT_LIST(rec); /*把记录加入结果集合中*/ 

/*再次遍历表中的所有记录,对比是否满足connect by后的条件,如果不满足则继续下一条, 

如果满足则再以该记录为根节点,然后调用RECURSE()继续递归寻找该节点下的子节点, 

如此循环直到找至叶子节点。*/ 

for rec_recurse in (select * from some_table) loop 

    if FULLFILLS_CONNECT_BY_CONDITION(rec_recurse.child, new_parent) then 

      RECURSE(rec_recurse,rec_recurse.child); 

    end if; 

end loop; 

end procedure RECURSE; 

 

三、使用探讨 

    从上面的执行原理可以看到connect by...start with...构造树的方式是:(1)如果是自上而下方式,则把表中的每一条记录都作为根节点来生成树,所以表中有多少条记录就会构造出多少棵树。(2)如果是自下而上的搜索方式,则把表中的每一条记录都作为叶子节点来生成分支,所以表中有多少条记录就会生成多少条分支。 

    因此如果表中的记录不是严格遵照每条记录都只能有一个父记录的原则,那么就可能有部分记录会存在于多棵树中,那么在查找记录的时候就可能会出现找到多条重复记录的异常情况

--1.Hierarchical Queries: START WITH and CONNECT BY PRIOR clauses 

--Hierarchical Queries

--START WITH and CONNECT BY PRIOR clauses.

 

SELECT employee_id, manager_id, first_name, last_name

FROM employee_jh

START WITH employee_id = 1

CONNECT BY PRIOR employee_id = manager_id;

 

EMPLOYEE_ID MANAGER_ID FIRST_NAME LAST_NAME

----------- ---------- ---------- ----------

          1          0 James      Smith

          2          1 Ron        Johnson

          3          2 Fred       Hobbs

          5          2 Rob        Green

          4          1 Susan      Jones

          6          4 Jane       Brown

          9          6 Henry      Heyson

          7          4 John       Grey

          8          7 Jean       Blue

         10          1 Kevin      Black

         11         10 Keith      Long

         12         10 Frank      Howard

         13         10 Doreen     Penn

 

13 rows selected.

 

--2.Using a Subquery in a START WITH Clause

SELECT LEVEL,

       LPAD(' ', 2 * LEVEL - 1) || first_name || ' ' || last_name AS employee

FROM employee_jh

START WITH employee_id = (SELECT employee_id FROM employee_jh WHERE first_name = 'Kevin' AND last_name = 'Black')

CONNECT BY PRIOR employee_id = manager_id;

 

     LEVEL EMPLOYEE

---------- -------------------------

         1  Kevin Black

         2    Keith Long

         2    Frank Howard

         2    Doreen Penn

 

--3.Including Other Conditions in a Hierarchical Query

SELECT LEVEL,

       LPAD(' ', 2 * LEVEL - 1) || first_name || ' ' ||

       last_name AS employee, salary

FROM employee_jh

WHERE salary <= 50000

START WITH employee_id = 1

CONNECT BY PRIOR employee_id = manager_id;

 

     LEVEL EMPLOYEE                      SALARY

---------- ------------------------- ----------

         3      Rob Green                 40000

         3      Jane Brown                45000

         4        Henry Heyson            30000

         3      John Grey                 30000

         4        Jean Blue               29000

         3      Keith Long                50000

         3      Frank Howard              45000

         3      Doreen Penn               47000

 

8 rows selected.

相关文章
|
8月前
|
网络协议 Linux 网络安全
使用frp时遇到的问题connect: connection refuseddial tcp xxxx:7000: connect: connection refused
最近在做的项目需要用到frp来做代理连接本地内网机,卡在最后启动客户端的时候,提示报错:login to server failed: dial tcp xxxx:7000: connect: connection refuseddial tcp xxxx:7000: connect: connection refused!!找了很多尝试的办法,现在给大家列一下希望对大家有帮助。
1470 0
|
关系型数据库 MySQL 数据库
ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
在连接数据库的时候,早上还好的时候,突然就坏了,看报错信息,发现连接拒绝,然后经过自己的排查,发现mysql数据服务竟然被关闭了,虽然关闭原因还未找到,但是解决这个问题的方法就是重新开启mysql服务就好
ConnectionRefusedError [SequelizeConnectionRefusedError]: connect ECONNREFUSED 127.0.0.1:3306
|
运维 网络协议 网络安全
Closed socket connection for client /39.103.162.230:56100 (no session established for client)
Closed socket connection for client /39.103.162.230:56100 (no session established for client)
324 0
Closed socket connection for client /39.103.162.230:56100 (no session established for client)
The connection to the server ip:6443 was refused - did you specify the right host or port
The connection to the server ip:6443 was refused - did you specify the right host or port
Failed to connect to 127.0.0.1 port 1080: Connection refused package 问题解决方法
Failed to connect to 127.0.0.1 port 1080: Connection refused package 问题解决方法
651 0
Failed to connect to 127.0.0.1 port 1080: Connection refused package 问题解决方法
|
Android开发
解决as connection refused: connect错误
解决as connection refused: connect错误
1012 0
解决as connection refused: connect错误
|
Linux 测试技术 网络安全
VNC connect:Connection refused(10061)
在Windows机器上使用VNC Viewer访问Linux服务器,有时候会遇到"connect:Connection refused(10061)"这个错误,导致这个错误出现的原因有多重,下面总结一下:     1:使用VNC Viewer时忘记加桌面号(一般为IP:桌面号,桌面号要看你自己的配置而定。
4114 0
|
JavaScript 中间件 Go
|
Oracle 关系型数据库 测试技术
20171120关于INBOUND_CONNECT_TIMEOUT设置
[20171120]关于INBOUND_CONNECT_TIMEOUT设置.txt --//上午翻看以前我的发的帖子,发现链接:http://www.itpub.net/thread-2066758-1-1.
1766 0