【问题标题】:Traverse a Tree With Oracle. Each Node Has A Property使用 Oracle 遍历树。每个节点都有一个属性
【发布时间】:2018-03-26 19:38:12
【问题描述】:

我在一个表中有一个简单的层次结构(使用 Oracle 数据库 11g)

A
|-B
  |-B1
|-C
|-D

每个节点都有一个与之关联的属性(Y 或 N)。

从根节点(父节点)遍历,我想得到每个分支中第一个具有Y属性的节点。

例如:

A
|-B (N)
  |-B1 (Y)
    |--B2 (N)
|-C (Y)
  |-C1 (Y)
    |--C2 (N)
|-D (Y)

这应该返回 B1、C 和 D。

请就如何做到这一点提供一些想法(代码需要针对时间进行优化)。

【问题讨论】:

  • 如何定义“第一”?你有一个父母,比如说 A,有四个孩子 A1、A2、A3 和 A4。 A2 和 A3 具有 Y 属性。哪一个是第一个具有该属性的?同样在您的示例中,为什么 A 没有设置属性(为 Y 或 N)?
  • 是的,A 也将具有 Y/N 属性。第一个 => 从根节点遍历时具有 Y 的第一个节点
  • 我了解您的第一个答案(关于 A 也具有 Y 或 N 属性)。我不明白你的第二个答案。 “从根节点遍历”不会给出节点的总排序。我举了一个例子:节点 A 的属性设置为 N。A 有四个孩子,其中两个孩子的属性设置为 Y。这两个孩子中的哪一个是“第一个”拥有该属性的孩子? “从根遍历”没有给子级排序;您必须提供额外的标准。

标签: oracle oracle11g hierarchy


【解决方案1】:

可能有比使用sys_connect_by_path 更有趣的方式,但我觉得它很容易理解。

create table hier_test (id varchar2(2), parent_id varchar2(2), prop varchar2(1));

insert into hier_test values ('A', null, 'N');
insert into hier_test values ('B', 'A', 'N');
insert into hier_test values ('C', 'A', 'Y');
insert into hier_test values ('D', 'A', 'Y');
insert into hier_test values ('B1', 'B', 'Y');
insert into hier_test values ('B2', 'B1', 'N');
insert into hier_test values ('C1', 'C', 'Y');
insert into hier_test values ('C2', 'C1', 'N');

select id from (
    select id, prop, sys_connect_by_path(prop, '>') as priors 
    from hier_test
    connect by parent_id = prior id
    start with id = 'A'
    )
where prop = 'Y' and priors not like '%Y>%';

编辑:sqlfiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多