2017-10-09 31 views
0


我有下面的數據代表僱員層次結構,我需要識別員工/主管的所有可能的排列組合。 我已經看過甲骨文樹步行似乎應該做的工作,但我不能完全得到它的工作。問題是我需要爲經理/員工的每個組合列出一行,這包括經理經理等。 (我已編輯添加姓名查詢)Oracle分層查詢 - 需要擴展信息

有沒有人有一個想法如何做到這一點?

DATA

SUPER SUP_NAME  EMP EMP_NAME 
^^^^^ ^^^^^^^   ^^^ ^^^^^^^ 
1  Big Boss   100 Sub Boss 
100 Sub Boss   200 Field Boss 
200 Field Boss  300 Field Emp 

期望的結果

SUPER EMP SUP_NAME  EMP_NAME 
^^^^^ ^^^ ^^^^^^^^  ^^^^^^^^ 
1  100 Big Boss  Sub Boss 
1  200 Big Boss  Field Boss 
1  300 Big Boss  Field Emp 
100  200 Sub Boss  Field Boss 
100  300 Sub Boss  Field Emp 
200  300 Field Boss Field Emp 
300   Field Emp 
+1

您到目前爲止嘗試過什麼查詢techGuy ..? –

+0

我剛纔嘗試了一個'思考斯蒂邦斯'(工會),它的工作很完美,但我無法弄清楚正確的方法來添加名稱,所以編輯了原始問題詢問如何將名稱也拉進去。 – TechGuy

+0

現在通過@ponderstibbons更新了答案,其中包含修改後的超級名稱列表,其中包含有效的名稱,請參閱頂部答案 – TechGuy

回答

2

使用connect_by_root標準分級查詢並添加員工誰是不使用unionminus經理:

select connect_by_root(super) super, emp from data connect by super = prior emp 
union 
select emp, null from data minus select super, null from data 

測試:

with data (super, emp) as (
    select 1, 100 from dual union all 
    select 100, 200 from dual union all 
    select 200, 300 from dual) 
select connect_by_root(super) super, emp from data connect by super = prior emp 
union 
select emp, null from data minus select super, null from data 

結果:

 SUPER  EMP 
---------- ---------- 
     1  100 
     1  200 
     1  300 
     100  200 
     100  300 
     200  300 
     300 
7 rows selected 
+0

好的答案!兩個建議雖然:(1)使用聯盟所有 - 沒有理由效率低得多的聯盟; (2)使用NOT IN子句(反連接),而不是MINUS操作效率低得多。 – mathguy

+0

你的解決方案就像一個魅力,我使用'聯盟',所以感謝您的幫助。我試圖添加Supervisor名稱和Emp名稱,但我似乎無法使其正常工作,我如何將它們添加到聯合查詢中? – TechGuy

+0

@ponderstibbons - 更新了您的答案,以添加到我添加到原始查詢的其他列中。 – TechGuy

0

嘗試此查詢。請注意,您需要一行包含300, NULL的行以在結果集中包含300, NULL

WITH yourtable (super, emp) 
    AS (SELECT 1, 
       100 
     FROM dual 
     UNION ALL 
     SELECT 100, 
       200 
     FROM dual 
     UNION ALL 
     SELECT 200, 
       300 
     FROM dual 
     UNION ALL 
     SELECT 300, 
       NULL 
     FROM dual), 
    datatable 
    AS (SELECT super, 
       Ltrim(Sys_connect_by_path(emp, ','), ',') path 
     FROM yourtable 
     START WITH emp IS NULL 
     CONNECT BY PRIOR super = emp) 
SELECT DISTINCT super, 
       Regexp_substr(path, '[^,]+', 1, LEVEL) AS data 
FROM datatable 
CONNECT BY Regexp_substr(path, '[^,]+', 1, LEVEL) IS NOT NULL 
ORDER BY super; 
+0

也許這會起作用,但效率很低。正如@ponderstibbons所示,使用標準的分層查詢功能。 – mathguy

+0

@mathguy:是的。沒有意識到'connect_by_root(super)' –