Обычно в результирующий набор добавляются предложения WHERE или HAVING, содержащие одно (и более) условное выражение, предназначенное для удаления ненужных записей из результирующего набора. Чаще всего в этих условных проверках используются фиксированные константы, например: "перечислить всех пользователей старше 40 лет" или "отобразить все счета-фактуры за период с января по июнь", что упрощает их написание и выполнение.
Однако возможны ситуации, когда условная проверка, используемая одним из запросов, использует значение, полученное вторым запросом, например, "перечислить всех пользователей старше среднего возраста" или "вывести счет-фактуру на самую большую сумму, полученный от самой малочисленной группы пользователей". Во всех таких случаях результаты, полученные одним запросом, зависят от данных, полученных с помощью другого запроса, что делает использование констант во внешнем запросе невозможным.
До версии 4.1 MySQL, в подобных случаях выполнялись запросы по отдельности, с последующим использованием наборов данных, полученных предыдущим запросом. Начиная с версии MySQL 4.1, появилась возможность выполнять подзапросы.
На свой страх и риск
Несмотря на то, что подзапросы очень полезны, они существенно снижают производительность СУБД MySQL. Так происходит потому, что еще на время издания этой книги, подзапросы поддерживались только альфа-версией MySQL 4.1, а производительность была неоптимальной для данных любого объема больше среднего. Правда, лучше вместо подзапросов в сценариях использовать объединения, удаление и модификацию сразу нескольких таблиц и временные таблицы, хотя в недалеком будущем ожидается существенное улучшение рабочих характеристик.
Что такое подзапрос?
Название подзапрос говорит само за себя: это запрос SELECT, вложенный в другой запрос. MySQL 4.1 позволяет вкладывать запросы один в другой, используя во внешнем
запросе результирующий набор, полученный внутренним запросом. В результате вместо выполнения одного (и более) отдельного запроса выполняется один запрос, содержащий один (и более) подзапрос.
При обнаружении такого вложенного запроса, MySQL сначала обрабатывает внутренний запрос, постепенно продвигаясь вверх по направлению к внешнему (основному) запросу. Результирующий набор, созданный каждым внутренним запросом по пути продвижения, присваивается внешнему порождающему запросу, который в свою очередь выполняется, и его результаты присваиваются внешнему запросу.
Подзапрос работает аналогично обычному запросу SELECT, за исключением того, что результирующий набор состоит из одного столбца, содержащего одно значение. Подзапрос может использоваться в любом месте, где используются выражения, он должен быть заключен в скобки и, как обычный запрос SELECT, содержать список столбцов (как замечено выше, это список, состоящий из одного столбца), предложение FROM с одним именем таблицы (и более), необязательные предложения WHERE, HAVING и GROUP BY.
Для того чтобы лучше понять, насколько полезным может быть подзапрос, рассмотрим простой пример с бухгалтерской базой данных воображаемой компании. Эта база данных состоит из следующих четырех таблиц.
4. Таблица branches_services: в этой таблице дается перечень филиалов и услуг, которыми они пользуются (это пара "идентификатор филиала - идентификатор услуги"). Она имеет внешние ключи по таблицам branches и services, соответственно.
А теперь, как вы уже знаете, можно получить полный перечень всех записей таблицы с помощью простого запроса SELECT * FROM .... Например, ниже представлен пере-
чень всех заказчиков.
С помощью объединения и предложения WHERE в операторе SELECT можно ограничить список записей только теми, что соответствуют определенному критерию - например, список заказчиков, филиалы которых расположены в Калифорнии.
А теперь немного усложним задачу. Скажем, нам необходимо получить список филиалов заказчика "Rabbit Foods Inc". Сейчас это можно сделать с помощью последовательности запросов SELECT, расположенных один за другим, сначала для получения идентификатора заказчика, который присвоен компании "Rabbit Foods", а затем, воспользовавшись этим идентификатором в другом запросе (он равен 104), получить список филиалов этого заказчика.
Таким образом, подзапрос позволяет объединять два и более запроса в один оператор и использовать результаты работы одного запроса в условном выражении другого.
Подзапрос должен возвратить один столбец, в противном случае MySQL не будет "знать", как обработать результирующий набор. Следующий листинг, демонстрирует что получится, если подзапрос возвратит результирующий набор, содержащий два столбца.
Листинг 11.6.
mysql> SELECT bdesc FROM branches WHERE cid = (SELECT cid, cname FROM clients WHERE cname = 'Rabbit Foods Inc');
ERROR 1239: Cardinality error (more/less than 1 columns)
Заметим, что допускается любая глубина вложения подзапросов. Рассмотрим пример со списком услуг, которыми пользуется заказчик "Sharp Eyes Detective Agency".
ТОП-10 популярных
Для работы с вещественными числами в MySQL предусмотрено три типа данных - это типы FLOAT, DOUBLE, DECIMAL. Числовой тип FLOAT...
БОЛЬШЕ БОЛЬШИХ LCD-мониторов
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Больше больших LCD-мониторов
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
Процесс вытеснения с рынка мониторов с электронно-лучевой трубкой (CRT) продолжается. О смещении акцентов в пользу LCD-мониторов теперь заявляют даже те...
НОУТБУК с блестящим экраном
Eсли выпустившая ноутбук фирма предлагает его в качестве «замены настольному ПК», то это должно подразумевать под собой нечто большее, чем...
Eсли выпустившая ноутбук фирма предлагает его в качестве «замены настольному ПК», то это должно подразумевать под собой нечто большее, чем...
Иди и пиши. TravelMate C100
Планшетный компьютер платформы Tablet PC обязан в первую очередь быть легким, способным достаточно долго работать без подзарядки батарей. Эти требования...
Планшетный компьютер платформы Tablet PC обязан в первую очередь быть легким, способным достаточно долго работать без подзарядки батарей. Эти требования...
Магнито-оптический дисковод DynaMO
Cейчас, когда традиционные флоппи-дисководы на долгие годы замерли в своем развитии, поиск альтернативных носителей продолжается, и ситуация, казалось бы, разрешилась...
Cейчас, когда традиционные флоппи-дисководы на долгие годы замерли в своем развитии, поиск альтернативных носителей продолжается, и ситуация, казалось бы, разрешилась...
Компьютер для гурманов.«Эксимер ДМ»
Российская компания «Эксимер ДМ», известная как производитель настольных компьютеров, рабочих станций, серверов и ноутбуков, выступила техническим спонсором проведения торжеств, посвященных...
Российская компания «Эксимер ДМ», известная как производитель настольных компьютеров, рабочих станций, серверов и ноутбуков, выступила техническим спонсором проведения торжеств, посвященных...
Для длинных строк, т.е. строк длиннее 255 символов, в MySQL предусмотрены типы BLOB (Binary Large Object, большой двоичный объект) и...
В дополнение к календарным типам, предназначенным для хранения даты и времени отдельно, MySQL также поддерживает гибридные типы данных DATETIME и...
Вообще, к изменению настроек сервера прибегают очень редко. В MySQL программа заранее настроена так, чтобы соответствовать самым распространенным и основным...
Все о MySQL. Подзапросы
28-12-2009
<< Предыдущая статья | Следующая статья >> |
Все о MySQL. Самообъединения | Все о MySQL. Типы подзапросов |