2011-10-06 60 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