Я хочу реализовать этот запрос NOT IN как серию OUTER JOIN, чтобы попытаться оптимизировать выполнение - PullRequest
0 голосов
/ 05 мая 2018

Я пытался следовать другим примерам, которые я видел на SO, но они просто не соответствуют моему варианту использования (или, я слишком туп, чтобы понять, как они применяются). У меня есть ситуация с использованием базы данных игрушек, где я хочу получить некоторую информацию, и мне нужно пройти через сводную таблицу, чтобы сделать это. Задача, которую я поставил перед собой:

Напишите запрос, в котором указаны полное имя и адрес электронной почты всех преподавателей, которые не проводят никаких занятий во 2 семестре 2018 года.

Таблица tutors содержит информацию о преподавателе, unittutor - это пивот, в котором есть tutor.staffID и unit.unitID, и, конечно, unit содержит все единицы.

Я могу легко добиться этого следующим образом:

SELECT
     t.firstName
    ,t.surname
    ,t.email
FROM tutor t
WHERE t.staffID NOT IN (
    SELECT ut.staffID
    FROM unittutor ut
    INNER JOIN unit u ON ut.unitID = u.unitID
    WHERE u.semester = 2 AND u.year = 2018
);

Я убежден (но вполне может ошибаться), что я могу реализовать это как два LEFT JOIN с ... однако все, что я пробовал, так и не сработало. Кто-нибудь может дать какой-нибудь общий совет относительно процесса, которому я могу следовать, чтобы достичь этого? Я чувствую, что спотыкаюсь о фильтр; когда я получаю unittutor s, очевидно, что репетитор, которого я ожидаю исключить (под которым я подразумеваю репетитора, с которым я хочу закончить), находится там, потому что этот репетитор фактически обучает юнит, но не в 2-м семестре. Когда Затем я присоединяюсь к unit, как отфильтровать единицы, которые соответствуют year = 2018 AND semester = 2?

У меня нет возможности писать много SQL на работе, но я не работаю над проектом, который может потребовать изрядного количества, и я хочу иметь возможность создавать наиболее оптимальный код из всех, что я могу.

1 Ответ

0 голосов
/ 05 мая 2018

Ваше "убедить" правильно. Две версии left join выглядят так:

SELECT t.firstName, t.surname, t.email
FROM tutor t LEFT JOIN
     unittutor ut
     ON ut.staffID = t.staffID LEFT JOIN
     unit u
     ON ut.unitID = u.unitID AND u.semester = 2 AND u.year = 2018
WHERE u.unitID IS NULL;

Важно, чтобы условия для u шли в предложении on, а не в предложении where. Если они входят в предложение where, внешнее объединение превращается в inner join и не выполняет то, что вы хотите.

Может возвращать дубликаты, которые можно удалить с помощью SELECT DISTINCT. Из-за дубликатов NOT EXISTS или NOT IN - лучший подход.

...