Результаты работы подзапроса вполне можно использовать и в предложении FROM внешнего оператора SELECT. Это можно проиллюстрировать на примере определения среднего количества услуг, которыми воспользовался каждый филиал. Поэтому сначала необходимо сгруппировать филиалы и вычислить среднее число услуг, которыми поль­зуются филиалы.
Подзапросы и предложение from
Таким образом, полученный подзапросом результат используется в предложении FROM внешнего запроса. Такая таблица на SQL-жаргоне называется производной таблицей.
Заметим, что при использовании результатов запросов, результирующая таблица, созданная внутренним запросом, должна иметь псевдоним, т.к. в противном случае MySQL не будет "знать", как ссылаться на ее столбцы. Если перезапустить предыдущий запрос без присвоения таблице псевдонима, получится следующее:
Листинг 11.31.
mysql> SELECT AVG(stotal) FROM (SELECT bid, COUNT (bid) AS stotal FROM branches_services GROUP BY bid);
ERROR 1246: Every derived table must have its own alias
А теперь пойдем дальше. Что делать, если вам необходимо перечислить филиалы, пользующиеся услугами, количество которых больше среднего?
Подзапросы и предложение from
Для того чтобы значительно ускорить работу этого запроса, целесообразно объеди­нить предыдущие запросы в один сложный запрос.
Подзапросы и предложение from
Для определения наименований заказчиков, соответствующих этим филиалам, доба­вим еще один запрос (и объединение).
Подзапросы и предложение from
Подзапросы и объединения
Как было показано в примерах этой главы, подзапросы могут отлично "сосущест­вовать", но зачем ограничивать себя только внутренними объединениями? С подзапро­сами также хорошо работают любые типы объединений, и, применив творческий подход, можно добиться отличного взаимодействия между двумя типами запросов.
Так, например, с помощью левого объединения можно получить список заказчиков, у которых в таблице branches нет соответствующих записей.
Подзапросы и предложение from
В этом случае запрос сохранит все записи с левой стороны объединения (перечень за­казчиков) и вставит значения NULL для всех записей справа (филиалы), которые не удовлетворяют условиям объединения. И что мы получим в результате? Все не имеющие филиалов заказчики будут иметь значение NULL (которое можно отбросить с помощью проверки IS NULL).
Это же можно сделать с помощью правого объединения с подзапросом.
Подзапросы и предложение from
В этом случае все записи на правой стороне объединения (клиенты) также будут при­сутствовать в результирующем наборе, а отсутствующие записи о филиалах будут обо­значены как NULL. Подзапрос выведет соответствующий идентификатор клиента, по ко­торому из таблицы customers можно будет получить наименование заказчика.
Интересен тот факт, что многие подзапросы могут быть представлены в виде объеди­нений и наоборот. Рассмотрим следующий пример, в котором с помощью подзапроса выдается перечень офисов, пользующихся услугой "Recruitment".
Подзапросы и предложение from
Подзапрос можно представить самообъединением, а самообъединение подзапросом. Рассмотрим следующий пример, в котором с помощью подзапроса будет получен пере­чень всех филиалов, размещенных в том же штате, где находится штаб-квартира корпо­рации "JV Real Estate".
Подзапросы и предложение from