Подзапросы можно использовать самыми различными способами:
■ в предложениях WHERE или HAVING;
■ в операторах сравнения или логических операторах;
■ с тестами принадлежности IN;
■ с логическими проверками EXISTS;
■ в предложении FROM;
■ с объединениями;
■ с запросами UPDATE и DELETE.
Рассмотрим эти вопросы подробнее в следующих разделах. 

Подзапросы и предложение where/having
MySQL позволяет включать подзапросы в предложения WHERE (для ограничения за­писей, возвращенных включающей конструкцией SELECT ... WHERE) или предложения HAVING (для ограничения групп, созданных включающим SELECT ... GROUP BY). Подзапросы, заключенные в скобки, могут обрабатываться операторами сравнения и ло­гическими операторами, в составе операторов IN или EXISTS.
Подзапросы и операторы сравнения
Когда подзапрос дает одно единственное значение, для сравнения его в условном вы­ражении, заданном в предложении WHERE или HAVING внешнего запроса, можно исполь­зовать операторы сравнения MySQL. Например, нам необходим перечень всех заказчиков, у которых есть два филиала. Сначала потребуется определить, сколько филиалов имеют заказчики,
Типы подзапросов
Типы подзапросов
В этом случае сначала обрабатывается внутренний запрос, в результате чего филиалы группируются по идентификатору заказчика и определяется количество записей (филиалов) для каждой группы. А количество заказчиков, которые имеют по два филиала, можно определить, просто отфильтровав данные предложением HAVING, и соответст­вующий идентификатор заказчика будет возвращен в главный запрос. После этого иден­тификаторы передаются таблице customers, которая передает соответствующее наиме­нование заказчика.
А как можно выбрать тех заказчиков, которые пользуются самыми дорогостоящими услугами?
Типы подзапросов
Типы подзапросов
Для получения наименования филиала и наименования заказчика вполне целесооб­разно прибегнуть к внутреннему объединению, которое работает достаточно быстро.
Типы подзапросов
Или можно воспользоваться подзапросом для получения списка филиалов, которые пользуются всеми имеющимися в наличии услугами, что видно из следующего примера.
Листинг 11.15.
mysql> SELECT branches.bid, COUNT (sid) FROM branches, branches_services WHERE branches.bid = branches_services.bid GROUP BY branches.bid HAVING COUNT (sid) = (SELECT COUNT(*) FROM services);
Empty set (0.04 sec)
Достаточно беглого взгляда на исходные данные, чтобы определить, что нет филиалов, которые бы пользовались всеми предоставляемыми услугами. Что же касается оп­ределения заказчиков, все филиалы которых пользовались бы всеми услугами, то это можно сделать с помощью следующего запроса.
Типы подзапросов
Подзапросы и оператор IN
Операторы сравнения можно применять только тогда, когда подзапрос возвращает результирующий набор, состоящий из одного значения. Однако в том случае, когда ре­зультирующий набор, возвращенный подзапросом, содержит сразу несколько значений, операторы сравнения заменяются оператором IN.
Оператор IN позволяет проверять наличие определенного значения в результирую­щем наборе и выполнить внешний запрос, если проверка прошла успешно. Для того что­бы продемонстрировать это, просмотрим перечень всех услуг, которыми пользуются оп­ределенные филиалы (скажем, филиал с идентификатором 1031). Для этого необходимо получить список идентификаторов всех услуг, которые используются в этом филиале.
Типы подзапросов
Типы подзапросов
В этом случае MySQL произведет выборку только тех записей таблицы services, которые соответствуют набору идентификаторов услуг, возвращенных подзапросом.
Как вариант этого запроса можно получить список всех филиалов, пользующихся ус­лугой "Accounting" (идентификатор услуги 1).
Типы подзапросов
Типы подзапросов
Ммм-да ... не очень-то информативно. Совсем не помешает наименование заказчика для каждого филиала. Оно определеяется с помощью быстрого объединения.
Типы подзапросов
 Предположим, нам необходим список особо ценных клиентов, ежемесячный счет от­дельных филиалов которых составляет не менее 2 тыс. долл. Эту информацию можно
получить (хотя есть и другие способы), воспользовавшись подзапросом с объединением, предложением GROUP BY и оператором IN.
Типы подзапросов