如何使用分层查询

问题描述:

考虑从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。 如何过滤树而不破坏它?

作为方法之一,你就可以开始从下向上遍历树 - 你会发现在他/她的名字的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.