【问题标题】:Select tree by leaf in Oracle Database在 Oracle 数据库中逐叶选择树
【发布时间】:2015-05-06 12:21:06
【问题描述】:

Oracle 中有分层查询,使用 CONNECT BY PRIOR。每个人都知道,如何按父母选择孩子,但我需要按孩子选择父母。

这是我的桌子:

ID  PID     NAME            TYPE
1   null    EARTH           PLANET
2   1       USA             COUNTRY
3   2       CALIFORNIA      STATE
4   3       Los_Angeles     CITY
5   3       San_Francisco   CITY
6   3       San_Diego       CITY

在我的应用中,我的 ID 是 San_Diego,我需要知道 San_Diego 在哪个国家/地区?我需要通过查询获取 USA (TYPE=COUNTRY) 吗? oracle分层结构如何选择?

【问题讨论】:

    标签: oracle hierarchy hierarchical-data


    【解决方案1】:

    层次结构意味着,表的一行是“父”,而另一行是“子”。 PRIOR 用于显示谁是谁。子句 CONNECT BY PRIOR EMPNO = MGR 的意思是,如果两行具有相同的值,但在 EMPNO 列中有一行,第二行在 MGR 列中,则第二个是“父”,第一个是“子”。所以,查询

    SELECT EMPNO,ENAME,MGR,LEVEL
    FROM TMP_PCH
    CONNECT BY PRIOR EMPNO = MGR
    START WITH MGR = 'John'
    

    返回约翰的所有下属(和约翰自己),并查询

    SELECT EMPNO,ENAME,MGR,LEVEL
    FROM TMP_PCH
    CONNECT BY PRIOR MGR = EMPNO
    START WITH MGR = 'John'
    

    返回 John(以及 John 本身)的所有 Boss。

    【讨论】:

    • 谢谢。我之前尝试过这样做,但出现 ORA-01436 错误。现在我修复了它,在了解之后,可以更改先验。
    【解决方案2】:

    您需要为connect by 创建正确的条件并从叶子“圣地亚哥”开始:

    select name 
      from (
        select * from test 
          connect by id = prior pid
          start with name='San_Diego')
      where type='COUNTRY'
    

    SQL Fiddle demo

    【讨论】:

      【解决方案3】:
      SELECT * FROM places_table
      WHERE type = 'COUNTRY'
      START WITH id = 6 -- San Diego
      CONNECT BY PRIOR pid = id;
      

      【讨论】:

        【解决方案4】:

        没有区别,你只需要在父端使用 PRIOR 即可。例如获取圣地亚哥市的树:

        WITH your_table AS (  
          SELECT 1 id, NULL pid, 'EARTH' name, 'PLANET' type FROM dual
          UNION
          SELECT 2 id, 1 pid, 'USA' name, 'COUNTRY' type FROM dual
          UNION
          SELECT 3 id, 2 pid, 'CALIFORNIA' name, 'STATE' type FROM dual
          UNION 
          SELECT 4 id, 3 pid, 'Los_Angeles' name, 'CITY' type FROM dual
          UNION 
          SELECT 5 id, 3 pid, 'San_Francisco' name, 'CITY' type FROM dual
          UNION
          SELECT 6 id, 3 pid, 'San_Diego' name, 'CITY' type FROM dual
        )
        SELECT id, name, level
        FROM your_table
        CONNECT BY id = PRIOR pid
        START WITH id = 6
        

        如果你只是想得到国家,你可以按级别过滤:

        WITH your_table AS (  
          SELECT 1 id, NULL pid, 'EARTH' name, 'PLANET' type FROM dual
          UNION
          SELECT 2 id, 1 pid, 'USA' name, 'COUNTRY' type FROM dual
          UNION
          SELECT 3 id, 2 pid, 'CALIFORNIA' name, 'STATE' type FROM dual
          UNION 
          SELECT 4 id, 3 pid, 'Los_Angeles' name, 'CITY' type FROM dual
          UNION 
          SELECT 5 id, 3 pid, 'San_Francisco' name, 'CITY' type FROM dual
          UNION
          SELECT 6 id, 3 pid, 'San_Diego' name, 'CITY' type FROM dual
        )
        SELECT id, name, level
        FROM your_table
        WHERE LEVEL = 3
        CONNECT BY id = PRIOR pid
        START WITH id = 6
        

        【讨论】:

        • 我的例子并不真实。我有公司结构,我不知道记录水平。我不能使用“LEVEL = 3”。
        • 好吧,我不知道。我根据你提供的数据回答。没有必要对此投反对票......
        猜你喜欢
        • 2020-10-24
        • 1970-01-01
        • 2014-09-15
        • 2021-04-27
        • 2012-07-17
        • 1970-01-01
        • 1970-01-01
        • 2011-12-27
        • 1970-01-01
        相关资源
        最近更新 更多