2017-10-07 94 views
1

考慮從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。 如何過濾樹而不破壞它?

回答

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.