Oracle层次结构查询从表中查找父项和子值

时间:2018-01-17 12:49:50

标签: oracle

我有一个源表,其中包含以下值:

   Col1          Col2
    A             B
    B             C
    E             F
    F             G
    G             H
    X             Y 

在此方案中,A是父级,b是A的子级 C是A的大孩子,父母和孩子的孩子应该是一个单一的孩子。 所以预期的输出是

输出:

A  B  C 
E  F  G  H
X  Y 

3 个答案:

答案 0 :(得分:2)

Oracle 11gR2设置

CREATE TABLE table_name ( Col1, Col2 ) AS
SELECT 'A', 'B' FROM DUAL UNION ALL
SELECT 'B', 'C' FROM DUAL UNION ALL
SELECT 'E', 'F' FROM DUAL UNION ALL
SELECT 'F', 'G' FROM DUAL UNION ALL
SELECT 'G', 'H' FROM DUAL UNION ALL
SELECT 'X', 'Y' FROM DUAL;

<强>查询

SELECT SUBSTR( SYS_CONNECT_BY_PATH( Col1, ' ' ) || ' ' || Col2, 2 ) AS path
FROM   table_name
WHERE  CONNECT_BY_ISLEAF = 1
START WITH Col1 NOT IN ( SELECT Col2 FROM table_name )
CONNECT BY PRIOR Col2 = Col1;

<强>解释

每个Col1开始(第4行),其中没有由相应Col2值标识的父行,并创建连接(第5行)Col1先前的SYS_CONNECT_BY_PATH的分层查询父行。

仅将输出过滤到那些作为分层树(第3行)叶子的行 - 即那些没有子项的行。

然后,您可以使用Col1生成一个字符串,其中包含从层次结构生成的树的每个分支的根到叶的所有Col2值,并将其与最终{{1}连接起来叶子上的值。 SUBSTR用于删除SYS_CONNECT_BY_PATH前置于路径中每个条目的前导空格分隔符。

<强>输出

PATH
-------
A B C
E F G H
X Y

答案 1 :(得分:1)

这是你搜索的内容吗?

SQL> with
  2    src as (select 'A' p#, 'B' c# from dual union all
  3            select 'B' p#, 'C' c# from dual union all
  4            select 'E' p#, 'F' c# from dual union all
  5            select 'F' p#, 'G' c# from dual union all
  6            select 'G' p#, 'H' c# from dual union all
  7            select 'X' p#, 'Y' c# from dual)
  8  select
  9    max(trim(sys_connect_by_path(p#, ' ') || ' ' || c#)) r#
 10  from
 11    src
 12  start with
 13    p# not in (select c# from src)
 14  connect by p# = prior c#
 15  group by connect_by_root(p#);

R#
--------------------------------------------------------------------------------
A B C
X Y
E F G H

答案 2 :(得分:-1)

可能这段代码可以帮到你。

WITH t1(id, parent_id) AS (
 -- Anchor member.
SELECT id,
     PARENT
FROM   table
WHERE  id = 'A'
UNION ALL
-- Recursive member.
SELECT t2.id,
     t2.PARENT
FROM   table t2, table t1
WHERE  t2.PARENT = t1.id
)
SELECT id, parent_id
FROM   t1;