Использование оператора EXISTS
EXISTS переводится как «существует» - это оператор, который возвращает логическое выражение (истина или ложь). Он берет подзапрос как аргумент и получает «истина», если тот производит любой вывод или «ложь», если тот не делает этого. Иными словами функция EXISTS возвращает значение «истина», если подзапрос возвращает хотя бы одну строку и «ложь», если подзапрос не возвращает ни одной строки. Функция EXISTS используется в условии WHERE. Так как внутренний оператор SELECT содержит произвольное количество столбцов, вместо списка столбцов обычно используют символ * (звездочка), что означает, что выбираются все столбцы. В качестве примера выведем фамилию, имя, отчество членов экипажа летавших в феврале 2008 года (если в таблице EQUIPAGE существует строка для выбранной личности с атрибутом EQ_FL_DATE попадающим в февраль 2008 года).[48] SELECT PR_NAME2 AS "Имя", PR_NAME3 AS "Отчество", PR_NAME AS "Фамилия" FROM PERSON WHERE EXISTS(SELECT * FROM EQUIPAGE E WHERE E. EQ_FL_DATE BETWEEN '1.02.08' AND '29.02.08' AND E. EQ_PR_CODE = PERSON. PR_CODE ) Для каждой строки-кандидата внешнего запроса (представляющей личность, проверяемую в настоящее время), внутренний запрос находит строки, которые относятся к этой личности (совпадение E. EQ_PR_CODE = PERSON.PR_CODE) и проверяет попадание даты вылета (EQ_FL_DATE) в заданный интервал. Альтернативным способом получения такого же результата будет использование связывания таблиц PERSON и EQUIPAGE и исключения дубликатов при помощи ключевого слова DISTINCT. Использование варианта IN с подзапросами Еще одним способом решить поставленную задачу является использование варианта IN. То есть во внутреннем запросе нужно из таблицы EQUIPAGE найти коды личностей (EQ_PR_CODE), даты вылета которых (EQ_FL_DATE) попадают в заданный интервал. Во внешнем запросе выводим фамилию, имя, отчество из таблицы PERSON коды которых, попадают в найденный перечень.[49]
SELECT PR_NAME2 AS "Имя", PR_NAME3 AS "Отчество", PR_NAME AS "Фамилия" FROM PERSON WHERE PR_CODE IN (SELECT EQ_PR_CODE FROM EQUIPAGE WHERE EQ_FL_DATE BETWEEN '1.02.08' AND '29.02.08' ) Использование NOT EXISTS Наиболее часто вместе с EXISTS используется оператор отрицания NOT. Если в условии нужно, чтобы строк запроса не существовало, использование подзапроса зачастую является единственной возможностью. Получим список членов экипажа, которые совершали полет в январе 2008 года, и при этом не разу не летали в феврале. Приведем первый вариант с использованием NOT EXISTS:[50] SELECT DISTINCT P. PR_NAME2 AS "Имя", P. PR_NAME3 AS "Отчество", P. PR_NAME AS "Фамилия" FROM PERSON P INNER JOIN EQUIPAGE E1 ON E1. EQ_PR_CODE = P. PR_CODE WHERE ( E1. EQ_FL_DATE BETWEEN '1.01.08' AND '31.01.08' ) AND NOT EXISTS (SELECT * FROM EQUIPAGE E2 WHERE E2. EQ_FL_DATE BETWEEN '1.02.08' AND '29.02.08' AND E2. EQ_PR_CODE = P. PR_CODE ) Разберем полученный запрос – внешний запрос выводит фамилию, имя, отчество для всех членов экипажа которые совершали полет в январе 2008 года, ключевое слово DISTINCT нужно, чтобы даже те члены экипажа, которые летали неоднократно, выводились только один раз. Во внешнем запросе используются псевдонимы таблиц P для PERSON и E1 для EQUIPAGE. В предложении WHERE соединяем два условия, первое ограничивает выводимый список членов экипажа теми, которые совершали полет в январе. Второе условие требует, чтобы текущая личность не совершала полет в течении февраля, т.е. чтобы за указанный период для этой личности не существовало строки в таблице EQUIPAGE. Во внешнем запросе для таблицы EQUIPAGE используется псевдоним Е2. Приведем вариант этого запроса с использованием NOT IN.[51] SELECT DISTINCT P. PR_NAME2 AS "Имя", P. PR_NAME3 AS "Отчество", P. PR_NAME AS "Фамилия" FROM PERSON P INNER JOIN EQUIPAGE E1 ON E1. EQ_PR_CODE = P. PR_CODE WHERE ( E1. EQ_FL_DATE BETWEEN '1.01.08' AND '31.01.08' ) AND (NOT P. PR_CODE IN (SELECT EQ_PR_CODE FROM EQUIPAGE WHERE EQ_FL_DATE BETWEEN '1.02.08' AND '29.02.08' ))
Здесь мы делаем следующее – во внутреннем подзапросе находим коды всех личностей из таблицы EQUIPAGE, которые совершали полет в феврале, внешний запрос выводит фамилию, имя, отчество для тех кто летал в январе 2008 и при этом среди них нет тех, кто содержится в результате вывода подзапроса (т.е. те кто летал в феврале).
Читайте также: II. Использование галереи фильтров Воспользуйтесь поиском по сайту: ©2015 - 2025 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...
|