日期:2014-05-16  浏览次数:20403 次

oracle树结构查询----connect by语法详解
CONNECT BY 语法相信大家可以从网上找到很多例子,在这里就不多说了。来描述一下我遇到的问题。
    表(fnd_flex_value)中的数据是这样的:
    TYPE_ID    PARENT_VALUE   CHILD_VALUE
    139048      2701                      270101
    139048      270101                27010101

    139058      2701                       270101
    139058      270101                   27010101

    执行如下语句:
    select * from fnd_flex_value ffv
     where type_id=139048
     start with child_value=270101
     connect by prior child_value=ffv.parent_value;
  
    执行结果为:
   TYPE_ID    PARENT_VALUE   CHILD_VALUE
    139048      2701                      270101
    139048      270101                  27010101
    139048      270101                  27010101

    最后一条记录重复了两次,我们想得到的结果应该只有前两条,那么第三条是怎么得到的呢,经过研究,个人认为可能是因为如下的原因(如果不正确,请大家改正,呵呵):
    在这段SQL的执行的时候,先执行了CONNECT BY,G最后才执行WHERE条件。
    那么循环得到的结果为:
    第一次循环(从start with child_value=2701)开始找数据:
    (1.1) 139048   2701 270101
    (1.2) 139058   2701 270101

    第二次循环(从(1.1)开始找数据:
    (2.1) 139048   270101 27010101
    (2.2) 139058   270101 27010101

    第三循环(从(1.2)开始)找数据:
    (3.1) 139048 270101   27010101
    (3.2) 139058 270101   27010101

    退出循环,最后执行where type_id=139048
    得到三条记录。

    如果想得到正确的结果,SQL语句应改为
   select * from
      (select * from fnd_flex_value where type_id=139048)ffv
     start with child_value=270101
     connect by prior child_value=ffv.parent_value;

=====================================================================

connect by 是结构化查询中用到的,其基本语法是:

select ... from tablename
where 条件3
start with 条件1
connect by 条件2;


例:
select * from table
start with org_id = 'HBHqfWGWPy'
connect by prior org_id = parent_id;


简单说来是将一个树状结构存储在一张表里,比如一个表中存在两个字段:

org_id,parent_id那么通过表示每一条记录的parent是谁,就可以形成一个树状结构。

用上述语法的查询可以取得这棵树的所有记录。

其中:

条件1 是根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。

条件2 是连接条件,其中用PRIOR表示上一条记录,比如 CONNECT BY PRIOR org_id = parent_id就是说上一条记录的org_id 是本条记录的parent_id,即本记录的父亲是上一条记录。

条件3 是过滤条件,用于对返回的所有记录进行过滤。


简单介绍如下:

早扫描树结构表时,需要依此访问树结构的每个节点,一个节点只能访问一次,其访问的步骤如下:

第一步:从根节点开始;

第二步:访问该节点;

第三步:判断该节点有无未被访问的子节点,若有,则转向它最