Базы данных. Учебное пособие

       

Подзапросы


Подзапрос  может  помещаться  в  команду  WHERE  запроса,  в  результате  чего  возможности  команды  WHERE  расширяются.  Рассмотрим  пример.

Запрос:  Вывести  специальности  рабочих,  назначенных  на  здание  435?

SELECT  Специальность

    FROM  Работник

    WHERE  № работника  IN

                        (SELECT   № работника

                            FROM   Работа

                            WHERE  № здания = 435 )

Подзапрос  в  этом  примере

                           

                         (SELECT   № работника

                            FROM   Работа

                            WHERE  № здания = 435 )

Запрос,  в  котором  содержится  подзапрос,  называется  внешним  запросом  или  главным  запросом.  Подзапрос  приводит  к  созданию  следующего  множества № работников:

 

№ Работника



   1412

   1235

Затем  это  множество  «№ Работников»  занимает  место  подзапроса  во  внешнем  запросе.  С  этого  момента  выполняется  внешний  запрос,  использующий  множество,  созданное  подзапросом.  Внешний  запрос  обрабатывает  каждую  строку  таблицы  «Работник»  в  соответствии  с  условием  WHERE.  Если  «№ работника»  строки  лежит  во  множестве,  созданном  подзапросом, то  «Специальность»  строки  выбирается  и  выводится  в  результирующей  таблице:

 

Специальность

 Штукатур

 Электрик

Очень  важно,  что  фраза  SELECT  подзапроса  содержит  «№ работника»  и  только   «№ работника.  В  противном  случае  фраза    WHERE  внешнего  запроса,  означающая,  что  «№ работника»  лежит  в  множестве  «№  работников»,  не  имела  бы  смысла.

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

Приведем  пример  подзапроса  внутри  подзапроса.

Запрос:  Вывести  фамилии  работников,  назначенных  на  здания  офисов.


              

  SELECT  Фамилия

  FROM  Работник

  WHERE  № работника  IN

                       (SELECT   № работника

                         FROM   Работа

                         WHERE  № здания   IN

                                             (SELECT   № здания

                                               FROM   Здание

                                                WHERE  Тип = 'Офис' ))

         

    Результат: 

     Фамилия

     И. Петров

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

Коррелированный  подзапрос  -  подзапрос,  результат  которого  зависит  от  строки,  рассматриваемой  главным  запросом.

Ниже  приведен  пример  такого  подзапроса.

      

Запрос:  Вывести  фамилии  работников,  чьи  почасовые  ставки выше,  чем  ставки  их  менеджеров.

                

  SELECT  Фамилия

  FROM  Работник  А

  WHERE  А. Недельная зарплата  >

                       (SELECT  B.Недельная зарплата

                         FROM   Работник  В

                         WHERE  В.№ работника = А.№ менеджера)

         

    Результат: 

     Фамилия

      К.  Иванов       

Обратите  внимание,  что  поскольку  «А. Недельная  зарплата»  может  сравниваться  только  с  одной  величиной,  подзапрос  должен  выдавать  только  одну  величину.  Эта  величина  меняется  в  зависимости  от  того,  какая  строка  А  рассматривается.  Таким  образом,  подзапрос  коррелирует  с  главным  запросом.


Содержание раздела