То, как я использую T-SQL, Существует ключевое слово?

Я потратил некоторое время на поиск такого файла и в итоге сам его создал, его можно получить здесь:

https://github.com/grammakov/us_cities_and_states/tree/ мастер

35
задан Malfist 27 May 2009 в 16:05
поделиться

5 ответов

Чтобы ответить на ваш вопрос об использовании ключевого слова 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 , то мы бы возвращали повторяющиеся строки всякий раз, когда в заказе было более одной позиции.)

Предикат NOT EXISTS также является полезно, например, для возврата набора заказов, которые не не имеют связанных line_items.

    SELECT o.*
      FROM order o
     WHERE NOT EXISTS
           ( SELECT 1
               FROM line_item li
              WHERE li.order_id = o.id
           )

Конечно, NOT EXISTS - лишь одна из альтернатив. Эквивалентный набор результатов может быть получен с использованием ВНЕШНЕГО соединения и теста 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 .)

Эффективность различных параметров запроса лучше всего оценивается наблюдением.

Различия в производительности

Иногда запрос с предикатом EXISTS не будет работать так же хорошо, как запрос с предикатом JOIN или IN . В некоторых случаях он может работать лучше. (С предикатом EXISTS подзапрос должен найти только одну строку, удовлетворяющую условию, а не ВСЕ совпадающие строки, как того требует JOIN .)

Эффективность различных параметров запроса лучше всего оценивается наблюдением.

Различия в производительности

Иногда запрос с предикатом EXISTS не будет работать так же хорошо, как запрос с предикатом JOIN или IN . В некоторых случаях он может работать лучше. (С предикатом EXISTS подзапрос должен найти только одну строку, удовлетворяющую условию, а не ВСЕ совпадающие строки, как того требует JOIN .)

Эффективность различных параметров запроса лучше всего оценивается наблюдением.

66
ответ дан 27 November 2019 в 06:56
поделиться

Попробуйте следующее:

SELECT
    tblTenantTransCode.ID 
    FROM tblCheckbookCode 
        INNER JOIN tblTenantTransCode ON tblCheckbookCode.ID=tblTenantTransCode.CheckbookCode
    WHERE tblCheckbookCode.Description = 'Rent Income'

Убедитесь, что вы проиндексировали tblCheckbookCode.Description .

0
ответ дан 27 November 2019 в 06:56
поделиться

Вам нужно использовать предложение IN:

select id from tblTenantTransCode
where tblTenantTransCode.CheckbookCode in
    (select id from tblCheckbookCode
     where description = 'rent income')

внутреннее соединение, вероятно, будет лучшим решением, хотя ...

select ttc.id from tblTenantTransCode as ttc
inner join tblCheckbookCode as tcc
    on ttc.CheckBookId = tcc.id
where tcc.description = 'rent income'
0
ответ дан 27 November 2019 в 06:56
поделиться

Вы описываете внутреннее соединение.

select tc.id 
from tblTenantTransCode tc 
   inner join tblCheckbookCode cc on tc.CheckbookCode = cc.CheckbookCode

РЕДАКТИРОВАТЬ: Это все еще внутреннее соединение. Я пока не вижу причин для использования предложения IN.

select *
from tblTransaction t
   inner join tblTenantTransCode tc on tc.id = t.TransactionCode
   inner join tblCheckbookCode cc on cc.id = tc.CheckbookCode
where cc.description = 'Rent Income'

РЕДАКТИРОВАТЬ: Если вы должны использовать предикат EXISTS для решения этой проблемы, см. Ответ @ spencer7953. Однако из того, что я вижу, вышеприведенное решение проще, и есть предположения об уникальности, основанные на том факте, что «Подзапрос» работает для вас (это не было бы в 100% случаев, если бы в этой таблице не было уникальности. ). Я также обращаюсь к

. Теперь я хочу выбрать Все транзакции. где их код транзакции соответствует идентификатору, возвращенному в подзапросе

моего ответа. Если бы запрос был чем-то вроде этого:

Теперь я хочу выбрать Все транзакции , когда любой код транзакции соответствует идентификатору, возвращенному в подзапросе.

Я бы использовал EXISTS, чтобы увидеть, существует ли какой-либо код транзакции в дочерней таблице, и вернуть каждую строку или ни одной, в зависимости от ситуации.

5
ответ дан 27 November 2019 в 06:56
поделиться

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

Объединение отфильтровывает любую транзакцию, не имеющую кода транзакции «Доход от аренды». Он возьмет всю запись из первой таблицы, построит подмножество второй таблицы (предложение WHERE ограничивает записи), а затем отфильтрует первую таблицу, в которой эта таблица вычисляет условие соединения.

SELECT 
    t.* 
FROM 
    tblTransaction t
    INNER JOIN tblTenantTransCode c ON
        t.TransactionCode = c.ID
    INNER JOIN tblCheckbookCode chk ON
        c.CheckbookCode = chk.ID
WHERE
    chk.Description = 'Rent Income'

Изменить: еще одно примечание: Избегайте использования SELECT * - всегда указывайте столбцы. Edit Dos: я пропустил, что было три таблицы. Исправлено! Спасибо, Спенсер!

1
ответ дан 27 November 2019 в 06:56
поделиться