Программирование >>  Построение запросов sql 

1 ... 46 47 48 [ 49 ] 50 51 52 ... 101


подзапросом, последовательно сравниваются со значением поля 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.

заявки любых абонентов с будет выглядеть следующим

REQUESTCD

ACCOUNTCD

EXECUTORCD

FAILURECD

INCOMINGDATE

EXECUTIONDATE

EXECUTED

005488

17.12.2001

20.12.2001

080270

31.12.2001

<null>

136169

06.11.2001

08.11.2001

115705

28.12.2001

<null>

080270

17.12.2001

27.12.2001

Рис. 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.

REQUESTCD

ACCOUNTCD

EXECUTORCD

FAILURECD

INCOMINGDATE

EXECUTIONDATE

EXECUTED

005488

17.12.2001

20.12.2001

136169

06.11.2001

08.11.2001

080270

17.12.2001

27.12.2001

Рис. 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.



1 ... 46 47 48 [ 49 ] 50 51 52 ... 101

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика