MyTetra Share
Делитесь знаниями!
Шаг 11 - Использование оператора EXISTS
01.11.2018
14:07
Текстовые метки: Access, SQL, EXISTS
Раздел: MSO - Access


Шаг 11 - Использование оператора EXISTS

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

Оператор EXISTS берет подзапрос, как аргумент, и оценивает его как верный, если подзапрос возвращает какие-либо записи и неверный, если тот не делает этого. Например, мы можем решить извлекать ли нам некторые данные из таблицы Заказчиков, если один и более заказчиков в этой таблице находятся в Москве.

SELECT cnum, cname, city

FROM Customers

WHERE EXISTS (

SELECT *

FROM Customers

WHERE city = 'Москва'

)



Результат:

cnum cname city

----- --------------------------------- ---------

2001 ТОО Рога и копыта Москва

2002 AО Бендер и К Одесса

2003 Фирма ХХХ Рязань

2004 Концерн "Дети лейтенанта Шмидта" Бобруйск

2006 Clemens Лондон

2007 ОАО "ООО" ТОМСК

2008 ОАО "Валют-транзит" Караганда



Внутренний подзапрос выбирает все данные для всех заказчиков из Москвы. Оператор EXISTS во внешнем условии отмечает, что подзапрос вернул некоторые данные, следовательно условие верное. Подзапрос будет выполнен один раз для всего внешнего запроса и имеет одно значение во всех случаях. Поэтому EXISTS, когда используется таким образом, делает условие верным или неверным для всех строк сразу.

В связанных подзапросах, предложение EXISTS оценивается для каждой строки таблицы, имя которой указано во внешнем запросе. Это дает возможность использовать EXISTS, как условие, которое генерирует разные ответы для каждой строки таблицы, указанной в основном запросе. Например, мы можем вывести торговых агентов, у которых несколько заказчиков.

SELECT DISTINCT snum

FROM Customers couter

WHERE EXISTS (

SELECT *

FROM Customers cinner

WHERE cinner.snum = couter.snum

AND cinner.cnum <> couter.cnum

)



Результат:

snum

-----------

1001

1002



Для каждой строки-кандидата внешнего запроса (представляющей заказчика проверяемого в данный момент), внутренний запрос находит строки, которые совпадают со значением поля snum (которое имел агент), но не со значением поля cnum (соответствующего другим заказчикам). Если любые такие строки найдены внутренним запросом, это означает, что имеется два разных заказчика, обслуживаемых одним продавцом. EXISTS поэтому верно для текущей строки и номер продавца (snum) будет выведен. Если бы DISTINCT не было указано, каждый из этих продавцов был бы выбран столько раз, сколько у него заказчиков.

Однако более полезно было бы вывести больше информации об этих агентах, а не только их номера. Это можно сделать объединив таблицу Заказчиков с таблицей Агентов:

SELECT DISTINCT first.snum, first.sname, first.city

FROM Salespeople first, Customers second

WHERE EXISTS (

SELECT *

FROM Customers third

WHERE second.snum = third.snum

AND second.cnum <> third.cnum)

AND first.snum = second.snum



Результат:

snum sname city

----- ------- ----------

1001 Иванов Москва

1002 Петров Хабаровск



Внутренний запрос такой же как и в предыдущем варианте. Внешний запрос - это объединение таблицы Агентов с таблицей Заказчиков.
Предыдущий пример показал, что оператор EXISTS можно использовать совместно с логическими операторами. Самым простым способом такого использования является применение оператора NOT - видимо самый частый вариант использования EXISTS. Один из способов нахождения продавцов только с одним заказчиком состоит в том, что предыдущий запрос инвертируется:

SELECT DISTINCT snum

FROM Customers couter

WHERE NOT EXISTS (

SELECT *

FROM Customers cinner

WHERE cinner.snum = couter.snum

AND cinner.cnum <> couter.cnum

)



Результат:

snum

-----------

1003

1004

1007



EXISTS достаточно простой оператор SQL, но весьма часто используемым. Следующим шагом будет овладение операторами ANY и ALL. Наше исследование базовых возможностей SQL в части выборки данных близится к завершению.


Предыдущий Шаг | Следующий Шаг | Оглавление
Автор Aidar Talibzhanov.

 
MyTetra Share v.0.52
Яндекс индекс цитирования