【问题标题】:How to get rows matching a condition using a hierarchical query如何使用分层查询获取匹配条件的行
【发布时间】:2017-10-07 11:25:56
【问题描述】:

考虑 Oracle 文档https://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm中的以下查询

SELECT employee_id, last_name, manager_id
   FROM employees
   CONNECT BY PRIOR employee_id = manager_id;

EMPLOYEE_ID LAST_NAME                        MANAGER_ID

    101     Kochhar                          100
    108     Greenberg                        101
    109     Faviet                           108
    110     Chen                             108
    111     Sciarra                          108
    112     Urman                            108
    113     Popp                             108
    200     Whalen                           101

我想过滤这棵树以获取姓氏中只有字母“a”的员工。 我可以使用 WHERE 子句,但问题是我不想只获得符合条件的行,而且如果他们不这样做,我也不想获得他们的父母事件,即我不想破坏一棵树。根据文档,Oracle 单独评估每一行的条件。例如,如果我使用 WHERE 子句,我会得到 id 为 101、109、111、112、200 的行。但我想得到 101、108、109、111、112、200。 如何过滤树而不破坏它?

【问题讨论】:

    标签: sql database oracle hierarchical-data


    【解决方案1】:

    作为其中一种方法,您可以从下往上开始遍历树 - 您找到一个姓名为 a 的员工,然后上树:

    Distinct 子句是为了摆脱重复的父母,我们需要第二个connect by 子句来翻转树。

     -- sample of data from your question
     with t1(EMPLOYEE_ID,LAST_NAME,MANAGER_ID) as(
       select 101, 'Kochhar'   ,  100 from dual union all
       select 108, 'Greenberg' ,  101 from dual union all
       select 109, 'Faviet'    ,  108 from dual union all
       select 110, 'Chen'      ,  108 from dual union all
       select 111, 'Sciarra'   ,  108 from dual union all
       select 112, 'Urman'     ,  108 from dual union all
       select 113, 'Popp'      ,  108 from dual union all
       select 200, 'Whalen'    ,  101 from dual
     )
    -- actual query 
    select employee_id
          , manager_id
          , concat(lpad('-', 3*level, '-'), last_name) as last_name
      from (
            -- using distinct to get rid of duplicate parents 
            select distinct last_name 
                  , employee_id
                  , manager_id
              from t1
              start with last_name like '%a%'
             connect by   employee_id  =  prior manager_id 
         ) q
       start with manager_id = 100
     connect by prior employee_id = manager_id
    

    结果:

      EMPLOYEE_ID MANAGER_ID LAST_NAME           
    ----------- ---------- --------------------
            101        100 ---Kochhar          
            108        101 ------Greenberg     
            109        108 ---------Faviet     
            111        108 ---------Sciarra    
            112        108 ---------Urman      
            200        101 ------Whalen        
    
    6 rows selected.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-17
      • 1970-01-01
      • 2012-02-26
      • 2017-08-12
      相关资源
      最近更新 更多