2016-05-30 149 views
1

我需要Informix分層sql查詢的一些幫助。我有表具有以下結構:給定層次結構中的任何子項,通過INFORMIX層次結構獲取完整樹SQL

create table empl_relation (
employee_id char(10), 
manager_id char(10)); 

employee_id  | manager_id 
5148    null    
5149    5148 
5150    5149 
5151    5148 
5152    5151 
5154    5148 
5155    5154 

我能夠成功運行下面的查詢:

SELECT employee_id, manager_id FROM empl_relation 
    START WITH employee_id = 5148 
    CONNECT BY PRIOR employee_id = manager_id 
    ORDER SIBLINGS BY employee_id; 

如上表中指定返回的確切層次。但是,我試圖在這裏實現不同的東西。我正在嘗試獲取給定層次結構中任何員工ID作爲輸入的相同結果集。例如,在查詢中,如果我將5154指定爲輸入employee_id,我應該能夠獲得所有父母及其子女以及輸入員工ID的子女和孫子女。確切地說,我想通過運行上面提到的查詢得到完全相同的結果集。

是否有可能在單個查詢來實現?如果是的話,你能幫我實現這個目標嗎?

      EDIT 

好吧,我想通實現這一目標的一種方式,但它涉及到執行2個查詢如下:

SELECT employee_id, manager_id FROM empl_relation 
    START WITH employee_id = 5150 
    CONNECT BY employee_id = PRIOR manager_id 
    ORDER SIBLINGS BY employee_id ; 

將返回:

employee_id  | manager_id 
5148  
5149     5148 
5150     5149 

然後我們可以檢索通過遍歷結果集,然後執行以下查詢來獲取完整的分層樹,從而在應用程序層上生成父級employee_id:

SELECT employee_id, manager_id FROM empl_relation 
    START WITH employee_id = 5148 
    CONNECT BY PRIOR employee_id = manager_id 
    ORDER SIBLINGS BY employee_id; 

這將正常工作,但它真的會很大,如果我能在一個單一的查詢實現這一目標。

回答

2

由喬納森的回答啓發,我想出了一個有點短版他的查詢如下

SELECT employee_id,manager_id FROM empl_relation 
START WITH employee_id = 
(SELECT employee_id 
    FROM empl_relation er 
    WHERE er.manager_id IS NULL 
    START WITH employee_id = 5150 CONNECT BY employee_id = 
    PRIOR manager_id) 
CONNECT BY 
PRIOR employee_id = manager_id 
ORDER BY employee_id; 

這也似乎工作正常。

+1

我相當肯定應該有一個更簡潔的方法來做到這一點,但我得到的語法錯誤。做得好。 –

+0

當我實際上在您的示例數據上運行此查詢時,出現錯誤「-284:子查詢返回的不完全是一行」。更奇怪的是,當我運行子查詢時,出現錯誤「-324:不明確的列(manager_id)」。當子查詢的選擇列表包含'manager_id'時,歧義列問題'消失':'SELECT employee_id,manager_id FROM empl_relation WHERE manager_id IS NULL START WITH employee_id = 5150 CONNECT BY employee_id = PRIOR manager_id'但可以'直接在主查詢中使用。測試:Mac OS X 10.11.5上的Informix 12.10.FC6。註釋? –

+0

好的。我不確定這裏發生了什麼事。 'SELECT僱員,MANAGER_ID從與EMPLOYEE_ID empl_relation START = (SELECT EMPLOYEE_ID FROM empl_relation ER WHERE er.manager_id IS NULL WITH EMPLOYEE_ID = 5150 CONNECT START BY EMPLOYEE_ID = PRIOR MANAGER_ID) CONNECT BY PRIOR EMPLOYEE_ID = MANAGER_ID ORDER BY employee_id;'看起來如果我在內部查詢中放置表的別名,那麼模糊的列問題就會消失。再次,不知道這裏發生了什麼。 – user3244615

2

這樣就結合你的兩個查詢爲一體,似乎工作:

SELECT employee_id, manager_id FROM empl_relation 
START WITH employee_id = (
        SELECT h.employee_id 
         FROM (SELECT employee_id, manager_id 
           FROM empl_relation 
          START WITH employee_id = 5150 
          CONNECT BY employee_id = PRIOR manager_id 
          ) AS h 
        WHERE h.manager_id IS NULL) 
CONNECT BY PRIOR employee_id = manager_id 
ORDER BY employee_id; 

基本上,這需要你的查詢工作了層次結構和運行它,然後過濾結果讓高層經理(僱員沒有經理),並使用該值作爲'從頂層的分層遞減'查詢中的開始。

5148 
5149 5148 
5150 5149 
5151 5148 
5152 5151 
5154 5148 
5155 5154 

我得到相同的結果與任何初始值:5148,5149,5150,5151,5152,5154,5155

+0

哇!這工作得很好!非常感謝你的幫助!! – user3244615