2011-10-06 65 views
3

我試圖找到一個好的,有效的方式來運行這樣的查詢:SQL多個共享WHERE條件

SELECT * 
    FROM tableA a 
WHERE a.manager IN ( SELECT id 
           FROM tableB b 
          CONNECT BY PRIOR b.id = b.manager_id 
          START WITH b.id = 'managerBob') 
     OR a.teamLead IN ( SELECT ID 
           FROM tableB b 
         CONNECT BY PRIOR b.ID = b.manager_id 
         START WITH b.ID = 'managerBob') 
     OR a.creator IN ( SELECT id 
           FROM tableB b 
         CONNECT BY PRIOR b.id = b.manager_id 
         START WITH b.id = 'managerBob') 

正如你所看到的,我試圖用多個WHERE子句,但每子句在等式的右側使用相同的數據集。如果我使用多個子句,它似乎運行速度非常緩慢,而且我確信這是因爲Oracle正在運行每個子查詢。有沒有辦法做出這樣的工作?

SELECT * 
    FROM tableA a 
WHERE a.manager, 
      a.teamLead, 
      a.creator in ( SELECT id 
           FROM tableB b 
          CONNECT BY PRIOR b.id = b.manager_id 
          START WITH b.id = 'managerBob') 

順便說一句,我很抱歉,如果這是我可以谷歌搜索,我不知道該怎麼稱呼這一點。

回答

11

Subquery factoring可以幫助:

WITH people AS 
( SELECT id 
     FROM tableB b 
    CONNECT BY PRIOR b.id = b.manager_id 
     START WITH b.id = 'managerBob' 
) 
SELECT * 
    FROM tableA a 
WHERE a.manager IN (SELECT id FROM people) 
     OR a.teamLead IN (SELECT id FROM people) 
     OR a.creator IN (SELECT id FROM people) 
+0

這個語法讓我感到困擾,但它是執行速度最快的。謝謝你告訴我它叫什麼,但這是試圖找出它的最令人沮喪的部分:) – monitorjbl

6

你可以這樣做:

WITH bob_subordinates AS (
( SELECT id 
     FROM tableB b 
CONNECT BY PRIOR b.id = b.manager_id 
START WITH b.id = 'managerBob') 
SELECT * FROM tableA a 
WHERE a.manager in (select id from bob_subordinates) 
    OR a.teamlead in (select id from bob_subordinates) 
    or a.creator in (select id from bob_subordinates) 

替代(檢查使用DISTINCT:如果ID不表B中唯一的,那麼這是不相等):

WITH bob_subordinates AS (
( SELECT DISTINCT id 
     FROM tableB b 
CONNECT BY PRIOR b.id = b.manager_id 
START WITH b.id = 'managerBob') 
SELECT DISTINCT a.* 
    FROM tableA a JOIN bob_subordinates b ON b.id IN (a.manager, a.teamlead, a.creator); 
2

按照註釋更新 - 嘗試

SELECT A.* FROM 
(SELECT bb.id FROM tableB bb CONNECT BY PRIOR bb.id = bb.manager_id START WITH bb.id = 'managerBob') B INNER JOIN TABLEA A ON B.ID IN (A.MANAGER, A.TEAMLEAD, A.CREATOR) 
+0

你可以簡化where子句:'WHERE b.id in(a.manager,a.teamlead,a .creator)' – Josh

+2

我希望人們會停止嘗試教人們使用','而不是'JOIN' :( – MatBailie

+0

看到上面的更新... – Yahia