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

1 ... 41 42 43 [ 44 ] 45 46 47 ... 101


3 абонентов подали 1 заявки

5 абонентов подали 2 заявки

1 абонентов подали 3 заявки

1 абонентов подали 5 заявки

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

соединением

В этом запросе сначала формируется производная таблица Ar, которая содержит информацию о номере лицевого счета абонента AbonentID и количестве поданных этим абонентом заявок Req Count.

Вид производной таблицы Ar представлен на рис. 3.84.

ABONENT ID

REQ COUNT

005488

015527

080047

080270

080613

115705

136159

136160

136169

443069

Рис. 3.84. Вид производной таблицы

Затем внешний запрос группирует строки из этой таблицы по количеству поданных заявок, подсчитывает количество строк в каждой группе и выводит данные в два столбца. Таким образом, получено, что одну ремонтную заявку подали три абонента, две заявки - пять абонентов и т. д. (рис. 3.83).

Допускается определение производной таблицы без использования конструкции

[AS] псевдоним (<список столбцов>).

Например, предыдущий пример может быть записан следующим образом: SELECT (Count (*) абонентов подали Req Count

заявки) AS Info FROM (SELECT A.AccountCD, Count (*) AS Req Count FROM Abonent A JOIN Request R ON A.AccountCD = R.AccountCD GROUP BY AccountCD) GROUP BY Req Count;. Результат выполнения запроса будет совпадать с представленным на рис. 3.83.

результатом,



NACHISLFACTCD

ACCOUNTCD

GAZSERVICECD

NACHISLSUM

NACHISLMONTH

NACHISLYEAR

136160

56,00

1999

136160

18,30

1998

136160

20,00

2001

136160

18,30

2000

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

В данном примере подзапрос в условии поиска представляет собой <скалярный подзапрос>. Он выполняется первым и возвращает единственное значение поля AccountCD = 136160. Оно помещается в условие поиска основного (внешнего) запроса так, что условие поиска будет выглядеть следующим образом: WHERE AccountCD = 136160 .

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

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

При простом сравнении используется <скалярный подзапрос> либо <подзапрос столбца>, если перед ним указан предикат ANY или ALL. Также <подзапрос столбца> используется при проверке на членство во множестве. В условии поиска с предикатом EXISTS или с предикатом SINGULAR используется <табличный подзапрос>. Использование подзапросов с предикатами ANY, ALL и EXISTS, SINGULAR будет рассмотрено позднее после изучения простых и связанных подзапросов.

Рассмотрим использование простых подзапросов в условиях поиска

предложений WHERE и HAVING.

Предположим, что известно ФИО абонента ШМАКОВ С.В., но не известно значение его поля AccountCD. Необходимо извлечь из таблицы NachislSumma все данные о начислениях абоненту ШМАКОВ С. В. Ниже приведен простой вложенный запрос, извлекающий требуемый результат из таблицы NachislSumma:

SELECT *

FROM NachislSumma

WHERE AccountCD = (SELECT AccountCD FROM Abonent

WHERE Fio = ШМАКОВ С.В.) ORDER BY NachislFactCD;.

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



Запрос предыдущего примера вернет во всех столбцах ТРЗ NULL-значения, если в таблице Abonent не будет абонента с ФИО ШМАКОВ С.В. Вложенные запросы, которые не производят никакого вывода (нулевой вывод), вынуждают рассматривать результат не как верный, не как неверный, а как неизвестный. Однако неизвестный результат имеет тот же самый эффект, что и неверный: никакие строки не выбираются основным запросом.

Запрос предыдущего примера не выполнится, если в таблице Abonent будет более одного абонента с ФИО ШМАКОВ С.В., т.к. вложенный запрос вернет более одного значения.

Например, следующий запрос, который должен найти абонентов, имеющих погашенные заявки на ремонт газового оборудования, не может быть выполнен из-за ошибки multiple rows in singleton select (многочисленные строки в единичном запросе SELECT):

SELECT * FROM Abonent WHERE AccountCD =

(SELECT AccountCD FROM Request

WHERE Executed=1 GROUP BY AccountCD);.

Это происходит потому, что вложенный запрос возвращает более одного значения. Если в БД будет одно значение или его вообще не будет, то запрос выполнится нормально, а если несколько, то возникнет ошибка.

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

SELECT * FROM Abonent WHERE AccountCD IN

(SELECT AccountCD FROM Request

WHERE Executed = 1 GROUP BY AccountCD);.

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

ACCOUNTCD

STREETCD

HOUSENO

FLATNO

PHONE

005488

АКСЕНОВ С.А.

556893

115705

МИЩЕНКО Е.В.

769975

443069

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

683014

136160

ШМАКОВ С.В.

982222

136169

ДЕНИСОВА Е.К.

680305

080613

ЛУКАШИНА Р.М.

254417

080047

ШУБИНА Т.П.

257842

080270

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

321002

Рис. 3.86. Результат выполнения вложенного запроса с предикатом IN

В данном примере подзапрос в условии поиска представляет собой <подзапрос столбца>, возвращающий различные значения поля AccountCD (005488, 080047, 080270, 080613 и т.д.), где Executed = 1. Затем выполняется внешний запрос, выводящий те строки из таблицы Abonent, для которых верно условие поиска AccountCD IN (005488, 080047, 080270, 080613 и т.д.) . Таким



1 ... 41 42 43 [ 44 ] 45 46 47 ... 101

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