|
Программирование >> Построение запросов sql
подзапросом, последовательно сравниваются со значением поля PaySum для каждой строки из таблицы PaySumma основного запроса. При первом обнаруженном совпадении сравнение прекращается и соответствующая строка выводится. Условие > ANY равносильно утверждению больше, чем минимальное из существующих , а условие < ANY - меньше, чем максимальное из существующих . Становится очевидным, что такие условия можно записать иначе, используя агрегатные функции MIN и MAX. Таким образом, предыдущий запрос можно переписать так: SELECT * FROM PaySumma WHERE PaySum > (SELECT MIN (PaySum) FROM PaySumma WHERE PayYear=2001 AND GazServiceCD=2) AND PayYear<2001 AND GazServiceCD=2;. Результат выполнения будет совпадать с результатом, представленным на рис. 3.100. Следует отметить, что использование сравнения = ANY эквивалентно использованию предиката IN. Рассмотрим использование предиката ALL. Например, требуется вывести информацию о ремонтных заявках абонентов, даты подачи заявок которых позднее, чем неисправностью с кодом, равным 2. Запрос образом: SELECT * FROM Request WHERE IncomingDate > ALL (SELECT IncomingDate FROM Request WHERE FailureCD=2);. Результат выполнения запроса представлен на рис. 3.101. заявки любых абонентов с будет выглядеть следующим
Рис. 3.101. Результат использования предиката ALL Если требуется вывести информацию о ремонтных заявках абонентов, даты выполнения заявок у которых позднее, чем даты выполнения заявок любых абонентов по неисправности с кодом, равным 2, то запрос будет выглядеть следующим образом: SELECT * FROM Request WHERE ExecutionDate > ALL (SELECT ExecutionDate FROM Request WHERE FailureCD=2);. В процессе выполнения данного запроса подзапросом формируется набор значений поля ExecutionDate, взятых из строк, где FailureCD=2. В результате условие поиска внешнего запроса будет выглядеть следующим образом: ExecutionDate > ALL (24.10.1998, 11.10.2001, 14.09.2001). Результат выполнения запроса представлен на рис. 3.102.
Рис. 3.102. Результат использования предиката ALL В ТРЗ не включены строки, где поле ExecutionDate имеет значение NULL, так как условие NULL > ALL( ) всегда возвращает результат NULL, а выводятся только те строки, для которых условие поиска истинно. Условие > ALL равносильно утверждению больше, чем максимальное , а условие < ALL - меньше, чем минимальное . Становится очевидным, что такие условия можно записать иначе, используя агрегатные функции MAX и MIN. Таким образом, предыдущий запрос можно переписать так: SELECT * FROM Request WHERE IncomingDate > (SELECT MAX (IncomingDate) FROM Request WHERE FailureCD=2);. Результат выполнения будет таким же, как и в предыдущем примере. Следует отметить, что использование сравнения <> ALL эквивалентно использованию предиката NOT IN, независимо от того, простой или связанный подзапрос используется. Рассмотрим использование связанного подзапроса с предикатом ALL. Пусть требуется вывести названия неисправностей, по которым все ремонтные заявки подавались позднее 1 мая 2001 года. Запрос будет выглядеть следующим образом: SELECT d.FailureNM FROM Disrepair d WHERE 01.05.2001 < ALL (SELECT r.IncomingDate FROM Request r WHERE d.FailureCD=r.FailureCD);. Результат выполнения запроса представлен на рис. 3.103. FAILURENM Засорилась водогрейная колонка Неисправна печная горелка Туго поворачивается пробка крана плиты Рис. 3.103. Результат использования связанного подзапроса с ALL Так как в этом примере используется связанный подзапрос, то он выполняется для каждой текущей строки из таблицы Disrepair (эта строка сохраняется во внешнем запросе под псевдонимом d). Вложенный запрос просматривает всю таблицу Request, чтобы найти строки, где значение поля r.FailureCD такое же, как значение d.FailureCD, и формирует набор значений поля IncomingDate для текущей строки-кандидата. Затем анализируется условие поиска основного запроса, чтобы проверить, меньше ли значение 01.05.2001 всех значений поля IncomingDate, полученных подзапросом. Если это так, то текущая строка-кандидат выбирается для вывода ее из основного запроса. 3.3.2.5. Предикат SINGULAR Совместно с подзапросами можно использовать предикат SINGULAR, который проверяет, возвращает ли подзапрос в точности одно значение. Если возвращается NULL или более одного значения, то SINGULAR дает ложь (а NOT SINGULAR - истину). Предикат SINGULAR похож на предикат ALL, за исключением того, что он проверяет наличие одного и только одного соответствующего значения в наборе. С предикатом SINGULAR могут использоваться как простые, так и соотнесенные подзапросы, однако часто использование простого запроса не имеет логического смысла. Следующим запросом, например, выводятся все данные об услугах газоснабжения, если оплата в размере 40 производилась только один раз: SELECT * FROM Services S WHERE SINGULAR (SELECT PayFactCD FROM PaySumma P WHERE PaySum=40);. Данный запрос не имеет практического смысла, так как данные об услугах и о значениях оплат никак не связаны. Поэтому с предикатом SINGULAR в основном используют соотнесенные подзапросы. Например, следующий запрос отыскивает всех абонентов, которые имеют только одну ремонтную заявку: SELECT * FROM Abonent A WHERE SINGULAR (SELECT RequestCD FROM Request R WHERE A.AccountCD=R.AccountCD);. Результат выполнения запроса представлен на рис. 3.104.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |