【问题标题】:Output records that match the condition, as well as their parent records up to the root record. Oracle SQL输出匹配条件的记录,以及它们的父记录直到根记录。甲骨文 SQL
【发布时间】:2018-05-14 18:40:12
【问题描述】:

有这样一张Oracle表:

+----+-----+--------+
| ID | PID |  NAME  |
+----+-----+--------+
|  1 |     | testX  |
|  2 |     | test2  |
|  3 |   2 | test3  |
|  4 |   3 | testX  |
|  5 |   3 | test5  |
|  6 |   3 | test6  |
|  7 |   4 | test7  |
|  8 |   5 | test8  |
|  9 |   3 | test9  |
| 10 |   4 | test10 |
| 11 |   5 | testX  |
| 12 |   5 | test12 |
+----+-----+--------+

,其中 pid 是父记录的 id。

需要输出所有符合条件的记录,以及它们的父记录,直到根记录。 此类父记录不应与在搜索阶段找到的父记录重复。

例如,在这个条件下where name = 'testX',应该得到这个结果:

+----+-----+-------+
| ID | PID | NAME  |
+----+-----+-------+
|  1 |     | testX |
|  2 |     | test2 |
|  3 |   2 | test3 |
|  4 |   3 | testX |
|  5 |   3 | test5 |
| 11 |   5 | testX |
+----+-----+-------+

怎么做?

附:甲骨文 11.2.0.4.0。

【问题讨论】:

  • 感谢您的回答。但是,如果有多个条件,并且在树中需要正确的输出顺序怎么办。
  • 不知道需求很难给你答案。我下面的回答仅基于您提供的信息。我也不确定“树中需要正确的输出顺序”是什么意思
  • 例如表中有Code1(varchar2)Code2(number)字段,需要按条件where name = 'test10' and code1 = 'test1' and code2 = 5查找。短语“树中需要正确的输出顺序”是指我需要将order siblings by 应用于查询,例如order siblings by name, code2, code1
  • 我可以根据史莱克的回答来做到这一点(期望的order siblings by),但到目前为止,我已经设法仅使用对表的 2 次访问来实现这一点,因为它看起来像 order siblings by 像我一样工作只有在start with pid is null的情况下才需要。

标签: sql oracle connect-by hierarchical-query


【解决方案1】:

我确信有一种更优雅的方法可以做到这一点,但这就是我想出的。

这是生成示例数据的 with 子句:

with testdata as
(select 1 ID,   null PID, 'testX' NAME from dual union all
select 2 ,      null,     'test2'      from dual union all
select 3 ,      2,        'test3'      from dual union all
select 4 ,      3,        'testX'      from dual union all
select 5 ,      3,        'test5'      from dual union all
select 6 ,      3,        'test6'      from dual union all
select 7 ,      4,        'test7'      from dual union all
select 8 ,      5,        'test8'      from dual union all
select 9 ,      3,        'test9'      from dual union all
select 10,      4,        'test10'     from dual union all
select 11,      5,        'testX'      from dual union all
select 12,      5,        'test12'     from dual)

这里是查询:

select distinct id, pid, name
from(
select sys_connect_by_path(name,'/') path,
       id, pid, name
from testdata
connect by prior PID = ID)
where instr(path,'/testX') > 0
order by id

我使用SYS_CONNECT_BY_PATH 来获取所有父母的姓名字段。然后我刚刚检查了testX 是使用instr 的字符串中的元素之一。

我的结果是:

ID      PID     NAME
1               testX
2               test2
3       2       test3
4       3       testX
5       3       test5
11      5       testX

【讨论】:

    【解决方案2】:

    这个简单的查询应该会有所帮助 -

    SELECT distinct id, pid, name FROM tab1
    connect by prior pid = id
    start with name = 'testX'
    order by id
    ;
    

    http://sqlfiddle.com/#!4/8da121/6/0

    输出 -

    ID  PID     NAME
    1   (null)  testX
    2   (null)  test2
    3   2       test3
    4   3       testX
    5   3       test5
    11  5       testX
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 2012-11-23
      • 2020-06-09
      • 1970-01-01
      相关资源
      最近更新 更多