如何使用分层查询获取与条件匹配的行

How to get rows matching a condition using a hierarchical query

考虑 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。 如何在不破坏树的情况下过滤树?

作为其中一种方法,您可以开始自下而上遍历树 - 您会在 his/her 中找到一个名字为 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.