2011-04-21 184 views
0

下面是一個查詢,它爲員工返回主管鏈,但它使用了一堆嵌套的SELECT語句。 我想知道這個查詢是否可以被重構爲更有效率。該查詢適用於3級管理授權員工參加培訓課程的應用程序。目前我們需要3個級別的批准,但是這可能會更改爲4個或更多。優化Oracle SQL查詢

SELECT badge as employee, 
    supervisor_badge as boss1, 
    (select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge) as boss2 
    (select supervisor_badge FROM hr_data level3 WHERE badge = 
      (select supervisor_badge FROM hr_data level2 WHERE badge = level1.supervisor_badge)) as boss3 
    FROM hr_data level1 WHERE BADGE = '123456'; 

徽章=僱員的ID
supervisor_badge =
博特字段是hr_data表員工的主管的徽章

  badge supervisor_badge 
      123456 111111 
      111111 454545 
      454545 332211 

輸出

employee  boss1  boss2  boss3 
123456   111111  454545  332211 
+0

你想讓它運行得更快嗎?還是希望它更加動態?所以你的關卡可以增長而不需要改變select語句? – Niklas 2011-04-21 17:27:03

+0

我覺得很容易維護。申請專家可能會要求我有5個級別的批准。下面的Mikes答案可以很容易地做到這一點。 – jeff 2011-04-21 18:36:52

回答

1

我沒有一個方便的數據庫來模擬這個,所以我將它。爲了清晰起見,我嘗試使用相同的命名約定。

SELECT level1.badge as employee 
     ,level2.badge as boss1 
     ,level3.badge as boss2 
     ,level3.supervisor_badge as boss3 
FROM hr_data level1 
     INNER JOIN hr_data level2 
      ON level2.badge = level1.supervisor_badge 
     INNER JOIN hr_data level3 
      ON level3.badge = level2.supervisor_badge 
WHERE  level1.badge = '123456' 

重要提示:其中存在的數據,在所有聯接這隻會返回記錄。要返回少於3個老闆的記錄(即只有boss1和boss2,但沒有老闆3),請將INNER JOIN報表更改爲LEFT JOIN

+0

謝謝邁克。您的查詢正確無誤地正常工作。它可以輕鬆添加或刪除關卡。 – jeff 2011-04-21 18:35:48

1

使用聯接,而不是子查詢。

SELECT 
    e.badge, b1.badge, b2.badge, b3.badge 
FROM 
    hr_data e 
LEFT JOIN hr_data b1 ON e.badge=b1.badge 
LEFT JOIN hr_data b2 ON b1.badge=b2.badge 
LEFT JOIN hr_data b3 ON b2.badge=b3.badge 
WHERE 
    e.badge='123456'; 

隨着級別是可變的,你可能要考慮使用一個存儲過程來爲內部水平的預先設定數量的循環(直到達到頂部,例如,你的CEO)。

+0

+1提醒我關於使用JOINS而不是SUBQUERIES。但是,您的查詢缺少主管徽章。 – jeff 2011-04-21 18:32:48