|
Программирование >> Построение запросов sql
3 абонентов подали 1 заявки 5 абонентов подали 2 заявки 1 абонентов подали 3 заявки 1 абонентов подали 5 заявки Рис. 3.83. Результат выполнения вложенного запроса в предложении FROM с соединением В этом запросе сначала формируется производная таблица Ar, которая содержит информацию о номере лицевого счета абонента AbonentID и количестве поданных этим абонентом заявок Req Count. Вид производной таблицы Ar представлен на рис. 3.84.
Рис. 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. результатом,
Рис. 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.
Рис. 3.86. Результат выполнения вложенного запроса с предикатом IN В данном примере подзапрос в условии поиска представляет собой <подзапрос столбца>, возвращающий различные значения поля AccountCD (005488, 080047, 080270, 080613 и т.д.), где Executed = 1. Затем выполняется внешний запрос, выводящий те строки из таблицы Abonent, для которых верно условие поиска AccountCD IN (005488, 080047, 080270, 080613 и т.д.) . Таким
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |