在项目中,有类似如下数据集:
A_Port   Z_Port
1         2
3         2
3         4
4         5
3         1
4         1
A_Port和Z_Port是一种连接关系,在上面的数据中,以前四条为例,表示的是1和2相连,3和2相连,3和3相连,4和5相连。
但在该数据库的设计中,却并不是一种的标准的树形关系,因此不能用标准的Connect BY Prior Z_Port = A_Port查询,
例如我要查找1-5的路径,却是A-Z-Z-A-A-Z-A-Z。
现在请大家帮忙,我要查找1-5的所有路径,在该示例中,明显看出有3条,1-2-3-4-5,1-3-4-5,1-4-5,如何写。
我也曾经考虑过将该数据集反向,但是在9i中,不支持NoCyCle,请大家帮忙啦。

解决方案 »

  1.   

    -- JUST TRY IT .. 
    SQL> SELECT * FROM TEST_NO_TREE;    A_PORT     Z_PORT
    ---------- ----------
             1          2
             3          2
             3          4
             4          5
             3          1
             4          16 rows selectedSQL> SELECT LTRIM(MAX(SYS_CONNECT_BY_PATH(RIGHTS, '-')), '-') ROADS
      2    FROM (SELECT TN.*,
      3                 DECODE(SIGN(Z_PORT - A_PORT), 1, Z_PORT, A_PORT) LEFTS,
      4                 DECODE(SIGN(Z_PORT - A_PORT), 1, A_PORT, Z_PORT) RIGHTS
      5            FROM TEST_NO_TREE TN) TT
      6   GROUP BY (ROWNUM - LEVEL)
      7   START WITH RIGHTS = 1
      8  CONNECT BY PRIOR LEFTS = RIGHTS;ROADS
    --------------------------------------------------------------------------------
    1-2-3-4-5
    1-3-4-5
    1-4-5
      

  2.   

    --或者这样写简化了子查询: JUST TRY IT ..
    SQL> SELECT LTRIM(MAX(SYS_CONNECT_BY_PATH(DECODE(SIGN(Z_PORT - A_PORT),
      2                                              1,
      3                                              A_PORT,
      4                                              Z_PORT),
      5                                       '-')),
      6               '-') ROADS
      7    FROM TEST_NO_TREE TT
      8   GROUP BY (ROWNUM - LEVEL)
      9   START WITH DECODE(SIGN(Z_PORT - A_PORT), 1, A_PORT, Z_PORT) = 1
     10  CONNECT BY PRIOR DECODE(SIGN(Z_PORT - A_PORT), 1, Z_PORT, A_PORT) =
     11              DECODE(SIGN(Z_PORT - A_PORT), 1, A_PORT, Z_PORT);ROADS
    --------------------------------------------------------------------------------
    1-2-3-4-5
    1-3-4-5
    1-4-5
      

  3.   

    To mantisXF:
       老兄的方法妙绝,但有两个问题:
       1.在我的机器上执行是1-2-3-4,1-3-4,1-4 ,不过看得出,结果是对的。
        2.老兄很巧妙地解决了A_Port和Z_Port交换的问题,该交换的才交换,但我的实际项目中,A_Port和Z_Port是varchar2(32),生成并无规律。
          希望老兄不吝赐教。
      

  4.   

    上面写的只是实现思路+方法。我的是10g的,5没有出来;然后在公司9i上测的时候也没有出来;郁闷。。 
    思路应该是没错的。我测试了很多数据,每到最后一位的时候数据就出不来。
    1: 我的思路是不是树让它变成树,这样就可以用CONNECT BY解决了。思路应该是对的。
    2: 我的想法是先插入的记录会比较小,所以是先有父在有子,因此通过比较大小来判断父子关系的。如果没有规律就让他变成有规律的。这只是对于现在这种情况,你可以参考一下。