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')
Кстати, мне жаль, если это то, что я мог бы погуглить, Я не знаю, как это назвать.
3 ответа:
Факторинг подзапросов может помочь:
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)
Вы можете сделать:
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: если идентификаторы не уникальны в таблице 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);