2

我有下表:

CREATE TABLE Z_BOM2 (A  VARCHAR2(4 CHAR), B  VARCHAR2(4 CHAR));
Insert into Z_BOM2 (A, B) Values ('A', 'B');
Insert into Z_BOM2 (A, B) Values ('A', 'C');
Insert into Z_BOM2 (A, B) Values ('C', 'D');
Insert into Z_BOM2 (A, B) Values ('C', 'F');
Insert into Z_BOM2 (A, B) Values ('D', 'E');
COMMIT;



SELECT * FROM Z_BOM2;
A   B
A   C
C   D
C   F
D   E

A是父母,B是孩子。

我想在查询中输入子值“E”和“F”,并且只为这两个应该是“A”的那些获得顶级父级。这是我正在使用的查询:

select SYS_CONNECT_BY_PATH (a,'/') as path, a, b, level, CONNECT_BY_ISLEAF AS leaf, CONNECT_BY_ROOT b top_level
  from Z_BOM2
  connect by prior a = b
  start with b IN ('E', 'F');

它返回以下内容:

/D  D   E   1   0   E
/D/C    C   D   2   0   E
/D/C/A  A   C   3   1   E
/C  C   F   1   0   F
/C/A    A   C   2   1   F

为什么它没有返回正确的顶级父级?

4

2 回答 2

2

顶级父级CONNECT_BY_ROOT基于您的起始条件和您在树上行走的方向。你正在倒着走树,所以“根”实际上是你的起始条件。

实际上,您已经有了想要的信息,但是在A列中,对于叶节点:

select SYS_CONNECT_BY_PATH (a,'/') as path, a, b, level,
  CONNECT_BY_ISLEAF AS leaf, CONNECT_BY_ROOT b top_level
from Z_BOM2
where CONNECT_BY_ISLEAF = 1
connect by prior a = b
start with b IN ('E', 'F');

PATH                 A    B         LEVEL       LEAF TOP_LEVEL
-------------------- ---- ---- ---------- ---------- ---------
/D/C/A               A    C             3          1 E         
/C/A                 A    C             2          1 F         

要仅获取您感兴趣的顶级值,请仅A在选择列表中包含列。

SQL 小提琴演示

这也适用于您在评论中添加的结构;SQL 小提琴。C得到B;J得到A;D 得到 A 和 B:

select CONNECT_BY_ROOT b query_val, a as top_level
from Z_BOM2
where CONNECT_BY_ISLEAF = 1
connect by prior a = b
start with b IN ('C', 'D', 'J');

QUERY_VAL TOP_LEVEL
--------- ---------
C         B         
D         A         
D         B         
J         A         
于 2015-02-24T10:24:34.313 回答
0

在 LEVEL 上设置 WHERE 条件

WITH t AS
   (select SYS_CONNECT_BY_PATH (a,'/') as path, a, b, level as LEV,
      CONNECT_BY_ISLEAF AS leaf, CONNECT_BY_ROOT b top_level
   from Z_BOM2
   connect by prior a = b
   start with b IN ('E', 'F'))
SELECT *
FROM t
WHERE LEV = 1;
于 2015-02-24T07:38:43.320 回答