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



好伙计们,

让我们假设有这样的树:

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

在此树中,字母应表示节点的名称,括号中的数字应表示某个值。 我知道如何通过分层查询(使用连接方式等(爬取所有节点。 但是,如果当前节点的值为空,我想检索(主(父节点的非空值。 因此,此类查询应生成如下所示的表:

命名父值 空 100 乙 A 50 乙 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

编辑:

与其使用带有父引用的表,不如考虑一个包含子引用的表,如下所示:

命名子值 阿 B 100 A D 100 乙 C 50 C E 空 E 空空 D B 30 B 空 20

,应转换为:

命名子值 阿 B 100 A D 100 乙 C 50 C E 50 E 空 50 D B 30 B 空 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 演示

我推荐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;

相关内容

  • 没有找到相关文章

最新更新