Oracle中start with connect by prior用法

最近看到Oracle中有一个很好用的查询,它就是start with connect by prior,说白了就是递归算法。 

如果表中存在层次数据,则可以使用层次化查询子句查询出表中行记录之间的层次关系
基本语法: 
[ START WITH CONDITION1 ]
CONNECT BY [ NOCYCLE ] CONDITION2
[ NOCYCLE ]参数暂时不解释
例: 
select empno, ename, job, mgr, hiredate, sal, comm, deptno, level as lv
from emp
start with empno = 7839
connect by (prior empno) = mgr;

表中存在层次数据 
数据之间的层次关系即父子关系,通过表中列与列间的关系来描述,如EMP表中的EMPNO和MGR。EMPNO表示雇员编号,MGR表示领导该雇员的人的编号,在表的每一行中都有一个表示父节点的MGR(除根节点外),通过每个节点的父节点,就可以确定整个树结构。

CONNECT BY [ NOCYCLE ] CONDITION2 层次子句作用
CONDITION2 [PRIOR expr = expr] : 指定层次结构中父节点与子节点之之间的关系。
CONDITION2 中的 一元运算符 PRIORY 必须放置在连接关系的两列中某一个的前面。在连接关系中,除了可以使用列名外,还允许使用列表达式。

1.START WITH
start with 子句为可选项,用来标识哪行作为查找树型结构的第一行(即根节点,可指定多个根节点)。若该子句被省略,则表示所有满足查询条件的行作为根节点。2.关于PRIOR PRIOR置于运算符前后的位置,决定着查询时的检索顺序。

2.1 从根节点自顶向下
--sql 1
select empno, mgr, level as lv
from scott.emp a
start with mgr is null
connect by (prior empno) = mgr
order by level;

--result 1

--分析
层次查询执行逻辑:
a.确定上一行(相对于步骤b中的当前行),若start with 子句存在,则以该语句确定的行为上一行,若不存在则将所有的数据行视为上一行。
b.从上一行出发,扫描除该行之外所有数据行。
c.匹配条件 (prior empno) = mgr
注意 一元运算符 prior,意思是之前的,指上一行
当前行定义:步骤b中扫描得到的所有行中的某一行
匹配条件含义:当前行字段 mgr 的值等于上一行字段 empno中的值,若满足则取出该行,并将
level + 1,
匹配完所有行记录后,将满足条件的行作为上一行,执行步骤 b,c。直到所有行匹配结束.

2.1 从根节点自底向上
--sql 2
select empno, mgr, level as lv
from scott.emp a
start with empno = 7876
connect by (prior mgr ) = empno
order by level;

--result 2

--分析
层次查询执行逻辑:
a.确定上一行(相对于步骤b中的当前行),若start with 子句存在,则以该语句确定的行为上一行,若不存在则将所有的数据行视为上一行。
b.从上一行出发,扫描除该行之外所有数据行。
c.匹配条件 (prior mgr ) = empno
注意 一元运算符 prior,意思是之前的,指上一行
当前行定义:步骤b中扫描得到的所有行中的某一行
匹配条件含义:当前行字段 empno 的值等于上一行字段 mgr 中的值,若满足则取出该行,并将
level + 1,
匹配完所有行记录后,将满足条件的行作为上一行,执行步骤 b,c。直到所有行匹配结束.
若不理解上一行当前行看此例子
select child_id, parent_id, level as lv
from table_name
start with child_id = 10
connect by (prior child_id) = parent_id;

step1.将下面一行作为上一行

step2..从上一行出发,扫描除该行之外所有数据行

step3.匹配条件 (prior child_id) = parent_id,
取出除上一行之外的数据行如

比较当前行的 parent_id 与上一行的 child_id,若相等则取出该行作为上一行的子行。
当上一行的子行全部取出后,将子行再作为上一行,重复步骤1,2
结果示意图如下

自顶向下,自下向上口诀:
start with child_id = 10 connect by (prior child_id) = parent_id
prior 和 子列在一起,表示寻找它的子孙,即自顶向下,和父列在一起,表示开始寻找她的爸爸,即自下向上。

原文地址:https://www.cnblogs.com/xiaocai0923/p/10836478.html

时间: 2024-11-05 21:55:39

Oracle中start with connect by prior用法的相关文章

oracle中 start with .. connect by prior.. 用法简介

我们经常会将一个比较复杂的目录树存储到一个表中.或者将一些部门存储到一个表中,而这些部门互相有隶属关系.这个时候你就会用到connect by prior start with.oracle 提供了start with connect by 语法结构可以实现递归查询. connect by 是结构化查询中用到的,其基本语法是: select ... from tablename start with 条件1 connect by prior 条件2 where 条件3; 例: select *

oracle 中 Start with...connect by 的用法(递归查询)

阿里电面问到了相关的知识,在网上找到这方面的文章. 这几个关键字是查询递归数据的,形成一个树状结构.目前只有oracle支持,其他数据都要结合存储过程实现 语法: select * from some_table [where 条件1] connect by [条件2] start with [条件3]; 其中 connect by 与 start with 语句摆放的先后顺序不影响查询的结果,[where 条件1]可以不需要.  [where 条件1].[条件2].[条件3]各自作用的范围都不

Oracle中start with...connect by子句的用法

connect by 是结构化查询中用到的,其基本语法是:select - from tablename start with 条件1connect by 条件2where 条件3;例:select * from tablestart with org_id = 'HBHqfWGWPy'connect by prior org_id = parent_id; 简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段:org_id,parent_id那么通过表示每一条记录的parent是谁

Oracle start with connect by prior 用法

Oracle start with connect by prior 用法  语法: select * from 表名 where 条件1 start with 条件2 connect by prior 当前表字段=级联表字段 start with与connect by prior语句完成递归记录,形成一棵树形结构,通常可以在具有层次结构的表中使用. start with表示开始的记录 connect by prior 指定与当前记录关联时的字段关系代码: --创建部门表,这是一个具有层次结构的

oracle中的exists 和not exists 用法详解

oracle中的exists 和not exists 用法详解 有两个简单例子,以说明 “exists”和“in”的效率问题 1) select * from T1 where exists(select 1 from T2 where T1.a=T2.a) ; T1数据量小而T2数据量非常大时,T1<<T2 时,1) 的查询效率高. 2) select * from T1 where T1.a in (select T2.a from T2) ; T1数据量非常大而T2数据量小时,T1>

ORACLE 中的 ROW_NUMBER() OVER() 分析函数的用法

Oracle 中的 ROW_NUMBER() OVER() 分析函数的用法 ROW_NUMBER() OVER(partition by col1 order by col2) 表示根据col1分组,在分组内部根据col2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内是连续且唯一的). 举例: SQL> DESC T1; Name                                           Null?    Type----------------------

oracle中的exists 和not exists 用法 in与exists语句的效率问题

博文来源(oracle中的exists 和not exists 用法):http://chenshuai365-163-com.iteye.com/blog/1003247 博文来源(  in与exists语句的效率问题):http://www.cnblogs.com/iceword/archive/2011/02/15/1955337.html (一) exists (sql 返回结果集为真) not exists (sql 不返回结果集为真) 如下: 表A ID NAME 1    A1 2

oracle 的 start with connect by prior 学习

语法: SELECT ... FROM    + 表名 START WITH         + 条件1 CONNECT BY PRIOR   + 条件2 WHERE              + 条件3 说明: 这个方法是用来查询树状结构的数据的.举个例子,我们有一个这样的结构 然后建一个这样的表,插入数据. CREATE TABLE TEST( ID NUMBER(2) PRIMARY KEY, PARENT_ID NUMBER(2) ); INSERT INTO TEST (ID, PAR

sql与oracle中有关case和decode的用法(行转列)及比较(转

引: 为了举例说明,这里创建了一张成绩表,如下图所示: 比较: 1.sql中,这两个函数我们仅能使用case,代码及结果如下: select name,       case Subject          when '语文' then 1          when '数学' then 2          when '英语' then 3   --else 3       end  as '科目代码'   from Results 同样的,我们可以用case实现行转列,代码及结果如下: s