SQL 多个共享 WHERE 条件

发布于 2024-12-08 12:24:14 字数 1161 浏览 0 评论 0原文

我正在尝试找到一种良好、有效的方法来运行这样的查询:

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')

顺便说一句,如果我可以在谷歌上搜索到这个内容,我很抱歉,我不知道该怎么称呼它。

I'm trying to find a good, efficient way to run a query like this:

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')

As you can see, I'm trying to use multiple WHERE clauses, but each clause is using the same dataset on the right-hand side of the equation. It seems to run very slowly if I use more than one clause, and I'm pretty sure that it's because Oracle is running each subquery. Is there a way to make something like this work?

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')

By the way, I'm sorry if this is something I could have Googled, I'm not sure what to call this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

流心雨 2024-12-15 12:24:14

子查询分解可能会有所帮助:

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)

Subquery factoring may help:

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)
千柳 2024-12-15 12:24:14

您可以执行以下操作:

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);

You can do:

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)

Alternative (check the use of DISTINCT: if ids are not unique in table B then this is not equivalent):

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);
短叹 2024-12-15 12:24:14

根据评论更新 - 尝试

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)

UPDATE as per comments - try

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文