递归SQL检索所有级别

时间:2017-09-28 15:32:09

标签: sql oracle recursive-query

使用Oracle的递归方法时,我无法检索所需的查询结果:

ID1     ID2
1       2
1       3
4       2
4       3
4       5

查询:

select sys_connect_by_path(id2,' -> ')
FROM Foo
  START WITH id1 = 1
  CONNECT BY PRIOR id1 = id2
ORDER BY 1;

仅输出1级层次结构(2,3)。我希望它检测树(1 - >(2,3) - > 4 - > 5),这样选择不同的 ID2 得到(2,3,5)。谢谢。

1 个答案:

答案 0 :(得分:0)

如果您使用的是Oracle 11.2或更高版本,则首选CTE(公用表表达式),而不是使用Oracle的 CONNECT BY 语句。

WITH
    aset -- Create pseudo table with ID2 as ID1 and vice versa
    AS
        (SELECT id1, id2
           FROM (SELECT id1, id2
                   FROM foo
                 UNION
                 SELECT id2, id1
                   FROM foo)
          WHERE id1 < id2),
    bset (id1, id2) -- Extract hierarchy from pseudo table
    AS
        (SELECT id1, id2
           FROM aset
          WHERE id1 = 1
         UNION ALL
         SELECT aset.id1, aset.id2
           FROM bset INNER JOIN aset ON bset.id2 = aset.id1
          WHERE bset.id1 <> aset.id2)
  SELECT DISTINCT bset.id2  -- Only keep values that were originally ID2
    FROM bset INNER JOIN foo ON bset.id2 = foo.id2
ORDER BY id2;

使用 CONNECT BY

是一回事
WITH
    aset
    -- Create pseudo table with ID2 as ID1 and vice versa
    AS
        (SELECT id1, id2
           FROM (SELECT id1, id2
                   FROM foo
                 UNION
                 SELECT id2, id1
                   FROM foo)
          WHERE id1 < id2),
    bset
    -- Extract hierarchy from pseudo table
    AS
        (    SELECT id2
               FROM aset
         START WITH id1 = 1
         CONNECT BY PRIOR id2 = id1)
  SELECT DISTINCT bset.id2
    -- Only keep values that were originally ID2
    FROM bset INNER JOIN foo ON bset.id2 = foo.id2
ORDER BY id2