with t as
  (select '001' A, '003' B
     from dual
   union all
   select '003' A, '007' B
     from dual
   union all
   select '007' A, '004' B
     from dual
   union all
   select '004' A, '017' B
     from dual
   union all
   select '017' A, '013' B
     from dual
   union all
   select '013' A, '024' B
     from dual
   union all
   select '024' A, '031' B
     from dual
   union all
   select '031' A, '021' B
     from dual)
 SELECT *
   FROM (select LTRIM(SYS_CONNECT_BY_PATH(A, ',') || ',' || B, ',') STR, T.B 
           from t
          start with A = '003'
         connect by A = PRIOR B) T1
  WHERE T1.B = '013';

解决方案 »

  1.   

    正向反向分别构建树就可以把多余的数据都剔除了,如果怕存在环路可以把connect by 改为connect by nocycle
    SELECT * FROM
        (select * from T
        START WITH A=P_START
        CONNECT BY PRIOR B=A)
    START WITH B=P_END
    CONNECT BY PRIOR A=B
      

  2.   

    3#的写法最好加上一个条件,看他的数据可能是一表到底的,按现在的写法可能比较慢
    SELECT *
       FROM (select LTRIM(SYS_CONNECT_BY_PATH(A, ',') || ',' || B, ',') STR, T.B 
               from t
              start with A = '003'
             connect by A = PRIOR B AND PRIOR A<>'013') T1
      WHERE T1.B = '013';