【问题标题】:Latest values of parents in hierarchical SQL/PL query分层 SQL/PL 查询中父级的最新值
【发布时间】:2019-12-12 23:59:28
【问题描述】:

大家好,

让我们假设这样一棵树:

一个 (100) | +--B (50) | | | C(空) | | | E(空) | +--D (30) | 乙 (20)

在这棵树中,一个字母代表一个节点的名称,括号中的数字代表一些值。 我知道如何使用分层查询(使用 connect by 等)来爬取所有节点。 但是,如果当前节点的值为空,我想检索(大)父节点的非空值。 因此,这样的查询应该产生如下表:

名称父值 一个空值 100 50 B D 20 CB 50 DA 30 欧共体 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

编辑:

您不妨考虑一个带有子引用的表,而不是带有父引用的表:

命名儿童价值 A B 100 100 BC 50 C E 空 E 空 空 数据库 30 B 空值 20

应该翻译成:

命名儿童价值 A B 100 100 BC 50 中英 50 E 空值 50 数据库 30 B 空值 20

【问题讨论】:

    标签: sql oracle hierarchical-data


    【解决方案1】:

    您的数据的问题是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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢,kfinity。尽管我发现 Ponder Stibbons 的方法也很有吸引力(因为省略了 connect by),但您的解决方案完全符合我的预期。
      猜你喜欢
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 2022-01-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多