|
Программирование >> Построение запросов sql
Вложенный запрос может ссылаться на таблицу, указанную во внешнем (основном) запросе (независимо от его уровня вложенности). Такой вложенный запрос называется соотнесенным или связанным из-за того, что его результат зависит от значений, определенных в основном запросе. При этом вложенный запрос выполняется неоднократно, по одному разу для каждой строки таблицы основного (внешнего) запроса, а не один раз, как в случае простого вложенного запроса. Строка внешнего запроса, для которой внутренний запрос каждый раз будет выполнен, называется текущей строкой-кандидатом. Процедура оценки, выполняемой при использовании связанного вложенного запроса, состоит из следующих шагов. 1. Выбрать строку из таблицы, именованной во внешнем запросе. Это будет текущая строка-кандидат. 2. Сохранить значение из этой строки-кандидата в псевдониме, который задан в предложении FROM внешнего запроса. 3. Выполнить вложенный запрос. Везде, где псевдоним, данный для внешнего запроса, найден, использовать значение для текущей строки-кандидата. Использование значения из строки-кандидата внешнего запроса во вложенном запросе называется внешней ссылкой. 4. Если связанный подзапрос используется в предложении WHERE или HAVING, то оценить условие поиска внешнего запроса на основе результатов вложенного запроса, выполняемого на шаге 3. Он определяет, выбирается ли строка-кандидат для вывода. Если связанный подзапрос используется в предложении SELECT, то выводятся поля, указанные в списке возвращаемых элементов основного запроса, и результат выполнения вложенного запроса. 5. Повторить процедуру для следующей строки-кандидата основной (внешней) таблицы и так далее, пока все строки таблицы не будут проверены. Таким образом, хотя общая структура связанного подзапроса такая же, как и простого подзапроса (употребляются те же самые предложения, порядок их следования не меняется), однако в предложении WHERE или HAVING связанного подзапроса содержится ссылка на столбец таблицы внешнего запроса, и алгоритм выполнения связанного подзапроса совершенно другой. Так как вложенный запрос содержит ссылки на таблицу (таблицы) основного запроса, то вероятность неоднозначных ссылок на имена столбцов достаточно высока. Поэтому если во вложенном запросе присутствует неполное имя столбца, то сервер БД должен определить, относится ли оно к таблице, указанной в предложении FROM самого вложенного запроса, или к таблице, указанной в предложении FROM внешнего запроса, содержащего данный вложенный запрос. Возможные неоднозначности при определении столбца устраняются использованием полного имени столбца. Двусмысленность при определении таблицы, используемой для конкретного отбора строк, устраняется с помощью псевдонимов таблиц, указываемых во внешнем и внутреннем запросе. 3.3.2.3.1. Связанные подзапросы в предложении SELECT Чаще всего в предложении SELECT применяются связанные вложенные, не простые запросы. Связанный вложенный запрос, возвращающий фамилии абонентов названия улиц, на которых они проживают, имеет вид: SELECT A.Fio, (SELECT S.StreetNM FROM Street S WHERE S.StreetCD = A.StreetCD) AS StreetNM FROM Abonent A;. Результат выполнения запроса представлен на рис. 3.93.
Рис. 3.93. Результат выполнения связанного подзапроса в предложении SELECT В соответствии с алгоритмом, описанным выше, данный запрос работает следующим образом. 1. Внешний запрос выбирает из таблицы Abonent строку с данными об абоненте, проживающем на улице с кодом, равным 3 (первая строка). 2. Сохраняет эту строку как текущую строку-кандидат под псевдонимом A. 3. Выполняет вложенный запрос, просматривающий всю таблицу Street, чтобы найти строку, где значение поля S.StreetCD такое же, как значение A.StreetCD (3). Из найденной строки таблицы Street извлекается поле StreetNM. 4. Для вывода выбираются значение поля A.Fio из основного запроса (АКСЕНОВ С. А.) и найденное значение поля S.StreetNM из вложенного запроса (ВОИкОВ ПЕРЕУЛОК). пока каждая строка таблицы Abonent не будет с использованием 5. Повторяются пп .1-4, проверена. Следует отметить, что ту же задачу можно решить следующего неявного соединения таблиц Abonent и Street: SELECT A.Fio, S.StreetNM FROM Abonent A, Street S WHERE A.StreetCD = S.StreetCD;, или следующего явного соединения этих же таблиц: SELECT A.Fio, S.StreetNM FROM Abonent A INNER JOIN Street S ON A.StreetCD = S.StreetCD;. Пусть необходимо вывести для каждого абонента номер его лицевого счета, ФИО и общее количество поданных им заявок. Для этого может использоваться следующий запрос: SELECT A.AccountCD, A.Fio, (SELECT COUNT (*) FROM Request R WHERE A.AccountCD = R.AccountCD) AS Request Count FROM Abonent A;. Результат выполнения запроса представлен на рис. 3.94.
Рис. 3.94. Результат соотнесенного вложенного запроса Данный запрос работает следующим образом. 1. Внешний запрос из таблицы Abonent выбирает строку c данными об абоненте, имеющем номер лицевого счета 005488 (первая строка). 2. Сохраняет эту строку как текущую строку-кандидат под псевдонимом A. 3. Выполняет вложенный запрос, просматривающий всю таблицу Request, чтобы найти все строки, где значение поля R.AccountCD такое же, как значение A.AccountCD (005488). С помощью агрегатной функции COUNT (3) подсчитывается общее количество таких строк.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |