分层 SQL/PL 查询中 parents 的最新值

Latest values of parents in hierarchical SQL/PL query

好人,

让我们假设一棵这样的树:

    A (100)
    |
    +--B (50)
    |  |
    |  C (NULL)
    |  |
    |  E (NULL)
    |
    +--D (30)
       |
       B (20)

在这棵树中,一个字母应该代表一个节点的名称,parent中的数字是一些值。 我知道如何使用分层查询(使用 connect by 等)遍历所有节点。 但是,如果当前节点的值为空,我想检索 (grand-)parent 节点的 non-null 值。 因此,这样的查询应该产生如下所示的 table:

NAME  PARENT  VALUE
A     NULL    100
B     A       50
B     D       20
C     B       50
D     A       30
E     C       50

你们中有人知道如何实现吗?

到目前为止的代码:

SELECT NAME, PARENT, 
   CASE VALUE
   WHEN IS NULL THEN (SELECT VALUE FROM SOMETABLE WHERE NAME = PARENT) -- this returns more than one value
   ELSE VALUE
   END CASE AS VALUE
FROM SOMETABLE
START WITH NAME='A'
CONNECT BY NOCYCLE PRIOR NAME = PARENT

编辑:

与其使用 parent 引用的 table,不如考虑使用 child 引用的 table,如下所示:

NAME  CHILD  VALUE
A     B      100
A     D      100
B     C      50
C     E      NULL
E     NULL   NULL
D     B      30
B     NULL   20

应该翻译成:

NAME  CHILD  VALUE
A     B      100
A     D      100
B     C      50
C     E      50
E     NULL   50
D     B      30
B     NULL   20

您的数据有问题 B 有两个父节点,也有子节点,所以这部分树被复制了。无论如何,您可以使用递归 CTE 轻松实现您的目标:

with c(name, parent, value) as (
    select name, parent, value from sometable where name = 'A' union all
    select t.name, t.parent, nvl(t.value, c.value) 
      from c join sometable t on c.name = t.parent)
select * from c

dbfiddle demo

我推荐 Ponder 的 CTE 答案。如果您出于某种原因必须使用 CONNECT BY,Oracle 没有提供多种方法来访问层次结构中的先前行 - 要么是 PRIOR(仅返回 1 级),要么是 CONNECT_BY_ROOT(仅查看根节点)或 SYS_CONNECT_BY_PATH(使用起来很麻烦,因为您需要求助于字符串操作)。

SELECT NAME, PARENT, 
   -- COALESCE(VALUE, PRIOR VALUE) AS VALUE, -- only works 1 level back
   regexp_substr(rtrim(SYS_CONNECT_BY_PATH(value, ','),','),'[^,]*$') as VALUE
FROM SOMETABLE
START WITH NAME='A'
CONNECT BY NOCYCLE PRIOR NAME = PARENT;