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

时间:2017-10-07 11:25:57

标签: sql database oracle hierarchical-data

请考虑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子句,我会获得带有ids 101,109,111,112,200的行。但我想获得101,108,109,111,112,200。 如何在不破坏树的情况下过滤树?

1 个答案:

答案 0 :(得分: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.