Ответ 1
Чтобы ответить на вопрос об использовании ключевого слова EXISTS, вот пример запроса, который использует предикат EXISTS, на основе запроса, как в настоящее время задано в вашем вопросе.
SELECT t.* FROM tblTransaction t WHERE EXISTS ( SELECT 1 FROM tblTenantTransCode ttc JOIN tblCheckbookCode cc ON (cc.ID = ttc.CheckbookCode AND cc.Description='Rent Income') WHERE ttc.ID = t.TransactionCode )
Дополнительная информация:
Мы все признаем, что существует множество операторов SQL, которые возвращают набор результатов, соответствующий указанным требованиям. И, вероятно, будут различия в наблюдаемой производительности этих запросов. Производительность особенно зависит от СУБД, режима оптимизатора, плана запроса и статистики (количество строк и распределение значений данных).
Одно из преимуществ EXISTS
заключается в том, что он ясно показывает, что нам не интересно возвращать какие-либо выражения из таблиц в подзапросе. Он служит для логического разделения подзапроса из внешнего запроса таким образом, что не существует JOIN
.
Другим преимуществом использования EXISTS
является то, что избегает возврата повторяющихся строк, которые были бы (могут быть) возвращены, если бы мы вместо этого использовали JOIN
.
Предикат EXISTS
может использоваться для проверки существования любой связанной строки в дочерней таблице без необходимости соединения. В качестве примера следующий запрос возвращает набор всех заказов, которые содержат по крайней мере один связанный с ним файл line_item:
SELECT o.* FROM order o WHERE EXISTS ( SELECT 1 FROM line_item li WHERE li.order_id = o.id )
Обратите внимание, что в подзапросе нет необходимости находить ВСЕ подходящие позиции, для удовлетворения условия нужно найти только одну строку. (Если бы мы должны были написать этот запрос как JOIN
, тогда мы возвращали бы повторяющиеся строки всякий раз, когда у заказа было более одной позиции.)
A NOT EXISTS
также полезен, например, для возврата набора заказов, у которых не есть любые связанные строки_имя.
SELECT o.* FROM order o WHERE NOT EXISTS ( SELECT 1 FROM line_item li WHERE li.order_id = o.id )
Конечно, NOT EXISTS
- это всего лишь одна альтернатива. Эквивалентный набор результатов может быть получен с использованием соединения OUTER и теста IS NULL (при условии, что у нас есть хотя бы одно выражение, доступное из таблицы line_item, которая не является NULL)
SELECT o.* FROM order o LEFT JOIN line_item li ON (li.order_id = o.id) WHERE li.id IS NULL
Кажется, что существует много обсуждений (относящихся к ответам на исходный вопрос) о необходимости использовать предикат IN
или нужно использовать JOIN
.
Эти конструкции являются альтернативами, но не нужны. Требуемый набор результатов может быть возвращен запросом без использования IN
и без использования JOIN
. Набор результатов может быть возвращен с запросом, который использует предикат EXISTS
. (Обратите внимание, что заголовок вопроса OP задал вопрос о том, как использовать ключевое слово EXISTS
.)
Вот еще один альтернативный запрос (это не мой первый выбор), но возвращаемый набор результатов удовлетворяет указанным требованиям:
SELECT t.* FROM tblTransaction t WHERE EXISTS ( SELECT 1 FROM tblTenantTransCode ttc WHERE ttc.ID = t.TransactionCode AND EXISTS ( SELECT 1 FROM tblCheckbookCode cc WHERE cc.ID = ttc.CheckbookCode AND cc.Description = 'Rent Income' ) )
В первую очередь, запрос должен возвращать правильный набор результатов, который удовлетворяет указанным требованиям, учитывая все возможные наборы условий.
Некоторые из запросов, представленных в качестве ответов здесь, НЕ возвращают запрошенный набор результатов, или если они это делают, они случайно делают это. Некоторые из запросов будут работать, если мы предварительно предположим что-то о данных, так что некоторые столбцы UNIQUE
и NOT NULL
.
Различия в производительности
Иногда запрос с предикатом EXISTS
не будет выполняться так же, как запрос с предикатом JOIN
или IN
. В некоторых случаях он может работать лучше. (С предикатом EXISTS
подзапрос должен найти только одну строку, которая удовлетворяет условию, а не находить ВСЕ подходящие строки, как это требуется JOIN
.)
Эффективность различных параметров запроса лучше всего измеряется наблюдением.