|
Программирование >> Построение запросов sql
образом, если используется предикат IN, то вложенный запрос выполняется один раз и формирует множество значений, используемых основным запросом. В любой ситуации, где используется реляционная операция сравнения (=), разрешается использовать IN. В отличие от запроса со знаком равенства, запрос с предикатом IN не потерпит неудачу, если больше чем одно значение выбрано вложенным запросом. Следует отметить, что с помощью предыдущего запроса получены данные об абонентах, которые имеют погашенные ремонтные заявки, но этот запрос не дает информации об абонентах, все заявки которых погашены. Чтобы получить данные об абонентах, все заявки которых погашены, предыдущий запрос можно модифицировать следующим образом: SELECT * FROM Abonent WHERE AccountCD IN (SELECT AccountCD FROM Request WHERE Executed = 1 GROUP BY AccountCD) AND AccountCD NOT IN (SELECT AccountCD FROM Request WHERE Executed = 0 GROUP BY AccountCD);. Результат выполнения этого запроса представлен на рис. 3.87. Абонентов с номерами лицевых счетов 115705 и 080270 нет в результирующей таблице, так как у этих абонентов имеются непогашенные заявки.
Рис. 3.87. Результат выполнения запроса с двумя вложенными запросами Во вложенном запросе возможно использование той же таблицы, что и в основном запросе. Например, если требуется вывести все данные об абоненте АКСЕНОВ С. А. и обо всех других абонентах, которые проживают с ним на одной улице, то запрос может иметь следующий вид: SELECT * FROM Abonent WHERE StreetCD = (SELECT StreetCD FROM Abonent WHERE Fio=АКСЕНОВ С.А.);. Результат выполнения запроса представлен на рис. 3.88.
Рис. 3.88. Результат использования одной и той же таблицы В данном примере подзапрос выполняется независимо от внешнего запроса, так как является простым. Сначала будет выполнен вложенный запрос, который выберет значение StreetCD из таблицы Abonent для абонента АКСЕНОВ С.А. Затем основной запрос выберет из той же таблицы Abonent строки со значением поля StreetCD, равным значению, выбранному вложенным запросом. Во вложенном запросе можно использовать агрегатные функции. Допустим, необходимо вывести абонентов и значения их начислений за 2001 год, превышающие среднюю сумму начислений по всем абонентам за этот год. Запрос будет иметь следующий вид: SELECT AccountCD, NachislSum, NachislMonth, NachislYear, (SELECT AVG(NachislSum) FROM NachislSumma GROUP BY NachislYear HAVING NachislYear=2001) AS Avg All FROM NachislSumma WHERE NachislSum > (SELECT AVG(NachislSum) FROM NachislSumma GROUP BY NachislYear HAVING NachislYear=2001) AND NachislYear=2001 ORDER BY 1;. Результат выполнения запроса представлен на рис. 3.89.
Рис. 3.89. Результат использования одной и той же таблицы В этом примере вложенный запрос выполняется один раз, возвращая среднее значение поля NachislSum за 2001 год. Затем это значение последовательно сравнивается с каждой выбираемой строкой из таблицы NachislSumma. Рассмотрим еще два примера. Для вывода погашенных ремонтных заявок с наиболее поздней датой поступления можно, используя следующий запрос: SELECT * FROM Request WHERE IncomingDate = (SELECT MAX (IncomingDate) FROM Request WHERE Executed=1);. Результат выполнения запроса представлен на рис. 3.90.
Рис. 3.90. Результат использования агрегатной функции Для вывода абонентов с наибольшими значениями оплаты можно использовать следующий запрос: SELECT Abonent.Fio, PaySumma.* FROM PaySumma, Abonent WHERE PaySum = (SELECT MAX(PaySum) FROM PaySumma) AND Abonent.AccountCD = PaySumma.AccountCD;. Результат выполнения запроса представлен на рис. 3.91.
Рис. 3.91. Результат выполнения запроса Вложенные запросы можно применять в предложении HAVING. Они могут использовать свои собственные агрегатные функции (если эти функции не возвращают многочисленных значений). Также в подзапросе, включенном в условие поиска предложения HAVING внешнего запроса, могут использоваться свои собственные предложения GROUP BY и HAVING. Следует помнить, что аргументы, указанные в HAVING, должны присутствовать в качестве аргументов и в GROUP BY. Например, для подсчёта числа абонентов с максимальными значениями оплаты за 2000 год можно использовать следующий запрос: SELECT COUNT(DISTINCT AccountCD), PaySum FROM PaySumma GROUP BY PaySum HAVING PaySum = (SELECT MAX(PaySum) FROM PaySumma WHERE PayYear = 2000);. Результат выполнения запроса представлен на рис. 3.92.
Рис. 3.92. Результат вложенного запроса в предложении HAVING
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |