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

1 ... 44 45 46 [ 47 ] 48 49 50 ... 101


4. Для вывода выбираются значения полей A.AccountCD и A.Fio из основного запроса (005488, АКСЕНОВ С. А.) и найденное вложенным запросом количество связанных строк в таблице Request (3).

5. Повторяются пп.1-4, пока каждая строка таблицы Abonent не будет просмотрена.

Если во внешнем запросе используется предложение GROUP BY, то выражения, указанные в нем, можно использовать внутри подзапросов.

Например, с помощью следующего связанного вложенного запроса можно получить общие суммы начислений и оплат по каждому абоненту:

SELECT AccountCD,

(SELECT Sum (NachislSum) FROM NachislSumma N WHERE N.AccountCD = P.AccountCD)

AS Nachisl, Sum (PaySum) AS Pay FROM PaySumma P

GROUP BY AccountCD;.

Результат выполнения запроса представлен на рис. 3.95.

ACCOUNTCD

NACHISL

005488

222,83

222,83

015527

84,96

84,96

080047

256,88

256,88

080270

221,30

221,30

080613

114,66

114,66

115705

747,95

747,95

126112

40,60

40,60

136159

16,60

16,60

136160

112,60

112,60

136169

160,66

160,66

443069

195,10

195,10

443690

39,47

39,47

Рис. 3.95. Результат соотнесенного вложенного запроса

Здесь в подзапросе вычисляется общая сумма всех начислений для абонента, отобранного внешним запросом. Затем возвращенное подзапросом значение выводится по каждому абоненту в результирующем столбце Nachisl. Из результата следует, что каждый абонент полностью оплатил начисленные ему суммы.

3.3.2.3.2. Связанные подзапросы в предложениях WHERE и HAVING

При использовании связанного вложенного запроса в условиях поиска предложений WHERE и HAVING он может представлять собой <скалярный подзапрос>, <подзапрос столбца> или <табличный подзапрос>, как и для простых вложенных запросов. Однако так как запрос связанный,



внутренний запрос выполняется отдельно для каждой строки внешнего запроса (текущая строка-кандидат).

Рассмотрим примеры, в которых используются <скалярный подзапрос> и <подзапрос столбца>. Подзапросы, представляющие собой

<табличный подзапрос>, будут рассмотрены позднее при изучении предикатов EXISTS и SINGULAR.

Например, чтобы вывести все сведения об абонентах, которые подали заявки на ремонт газового оборудования 17 декабря 2001 года, можно использовать следующий связанный вложенный запрос:

SELECT * FROM Abonent Out

WHERE 17.12.2001 IN

(SELECT IncomingDate FROM Request Inn WHERE Out. AccountCD = Inn. AccountCD);.

Результат выполнения запроса представлен на рис. 3.96.

ACCOUNTCD

STREETCD

HOUSENO

FLATNO

PHONE

005488

АКСЕНОВ С.А.

556893

080270

ТИМОШКИНА Н.Г.

321002

Рис. 3.96. Результат связанного вложенного запроса в предложении WHERE

В этом примере Out и Inn - это псевдонимы таблиц Abonent и Request соответственно (могут задаваться произвольно). Так как значение в поле AccountCD внешнего запроса меняется (при переборе строк), внутренний запрос должен выполняться отдельно для каждой строки внешнего запроса. В этом примере SQL осуществляет следующую процедуру: 1) выбирает строку c данными об абоненте, имеющем номер лицевого счета 005488 (первая строка) из таблицы Abonent;

сохраняет эту строку как текущую строку-кандидат под псевдонимом

2) 3)

Out;

выполняет вложенный запрос, просматривающий всю таблицу Request, чтобы найти строки, где значение поля Inn.AccountCD - такое же, как значение Out.AccountCD (005488). Затем из каждой такой строки таблицы Request извлекается поле IncomingDate. В результате вложенный запрос, представляющий собой <подзапрос столбца>, формирует набор значений поля IncomingDate для текущей строки-кандидата;

после получения набора всех значений поля IncomingDate для поля AccountCD=005488 анализируется условие поиска основного запроса, чтобы проверить, имеется ли значение 17 декабря 2001 в наборе всех значений поля IncomingDate. Если это так (а это так), то выбирается строка с номером лицевого счета 005488 для вывода ее из основного запроса;

повторяются пп.1-4 (для строки с номером лицевого счета 015527 и т.д.), пока каждая строка таблицы Abonent не будет проверена.



Ту же самую задачу можно решить, используя естественное соединение таблиц Abonent и Request следующим образом:

SELECT AccountCD, StreetCD, HouseNO, FlatNO, Fio, Phone

FROM Abonent out NATURAL JOIN Request inn WHERE inn.IncomingDate = 17.12.2001;.

Результат выполнения будет совпадать с результатом, представленным на рис. 3.96. Однако следует обратить внимание на наличие существенных различий между соединением таблиц и вложенными соотнесенными запросами. Дело в том, что запросы с использованием соединения таблиц формируются СУБД как строки из декартова произведения таблиц, перечисленных в предложении FROM. В случае же с вложенным соотнесенным запросом строки из произведения таблиц не вычисляются благодаря использованию механизма строки-кандидата. Вывод в связанном вложенном запросе формируется в предложении SELECT внешнего запроса, в то время как соединения могут выводить строки из обеих соединяемых таблиц (при указании символа * в предложении SELECT). Но даже если столбцы для вывода при соединении таблиц указаны явно (см. предыдущий пример), то сначала все равно формируется декартово произведение.

Каждый SQL-запрос можно оценить с точки зрения используемых ресурсов сервера БД. На практике большинство СУБД подзапросы выполняют более эффективно. Тем не менее, при проектировании комплекса программ с критичными требованиями по быстродействию разработчик должен проанализировать план выполнения SQL-запроса для конкретной СУБД. Тестирование в реальных условиях - единственный надежный способ решить, что лучше работает для конкретных потребностей.

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

SELECT * FROM Executor E

WHERE 4<= (SELECT COUNT(R.RequestCD) FROM Request R WHERE E.ExecutorCD = R.ExecutorCD);.

Результат выполнения запроса представлен на рис. 3.97.

EXECUTORCD

СТАРОДУБЦЕВ Е.М.

ШУБИН В.Г.

ШЛЮКОВ М.К.

Рис. 3.97. Результат сравнения вложенного запроса с константой



1 ... 44 45 46 [ 47 ] 48 49 50 ... 101

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