Виктор Гольцман - MySQL 5.0. Библиотека программиста
Далее мы рассмотрим возможности комбинирования запросов.
Вложенные запросы
Результатом запроса является массив данных в виде таблицы, поэтому вы можете использовать результат одного запроса в другом запросе. Во многих случаях вложенными запросами можно заменить объединение таблиц. Например, получить список имен клиентов, когда-либо заказывавших товар № 5, можно с помощью вложенного запроса:SELECT name FROM Customers
WHERE id IN
(SELECT DISTINCT customer_id FROM Orders
WHERE product_id = 5);Здесь вложенный запрос получают из таблицы Orders (Заказы) номера клиентов, заказавших товар № 5. Для обработки результатов подзапроса мы применили оператор IN, который возвращает истинное значение (TRUE), если элемент слева от оператора совпадает с одним из элементов списка справа от оператора. В данном случае оператор IN проверяет, содержится ли номер клиента (значение столбца id) в списке номеров, выданных подзапросом. Таким образом, внешний запрос выводит имена тех клиентов, номера которых получены в результате подзапроса (табл. 2.14). Таблица 2.14. Результат выполнения запроса
Такой же результат можно получить и с использованием объединения таблиц:SELECT DISTINCT name FROM Customers, Orders WHERE Customers.id = customer_id AND product_id = 5;
Однако не всегда вложенные запросы и объединения таблиц взаимозаменяемы. В частности, запросы с объединениями могут выводить данные из всех участвующих в запросе таблиц, а запросы с вложенными запросами, – только из таблиц, участвующих во внешнем запросе. А с помощью запросов, использующих групповые (агрегатные) функции в подзапросах, можно получить результат, не достижимый другими способами. Например, вывести заказ с наибольшей суммой можно только с помощью вложенного запроса, подсчитывающего максимальную сумму заказа:
SELECT * FROM Orders WHERE amount = (SELECT MAX(amount) FROM Orders);
Во вложенном запросе групповая функция MAX возвращает наибольшее из значений столбца amount (сумма) таблицы Orders (Заказы) – в данном случае 22 000. Внешний запрос, в свою очередь, выводит те строки таблицы Orders, в которых значение столбца amount равно значению, выданному подзапросом, то есть 22 000 (табл. 2.15). Таблица 2.15. Результат выполнения запроса
О других групповых функциях, а также об операторах, используемых для обработки результатов подзапроса, вы узнаете в главе 3.
Отмечу, что можно включить в запрос одновременно и подзапросы, и объединения таблиц. Тем самым вы можете получить еще более мощные возможности для поиска и отбора данных.
В следующем подразделе мы рассмотрим еще один способ совместного использования запросов – объединение запросов.Объединение результатов запросов
Чтобы объединить несколько запросов в одну SQL-команду и, соответственно, объединить результаты запросов, используется ключевое слово UNION. Запросы, объединяемые с помощью UNION, должны выводить одинаковое количество столбцов, и типы данных столбцов должны быть совместимы. При объединении результатов автоматически удаляются повторяющиеся строки; чтобы запретить удаление повторяющихся строк, вместо слова UNION нужно использовать выражение UNION ALL. Наконец, строки объединенного запроса можно упорядочить с помощью выражения ORDER BY. В качестве примера рассмотрим запрос, выводящий информацию о заказах с наибольшей и наименьшей суммой заказа:
SELECT * FROM Orders
WHERE amount = (SELECT MAX(amount) FROM Orders)
UNION
SELECT * FROM Orders
WHERE amount = (SELECT MIN(amount) FROM Orders)
ORDER BY 1;Результатом выполнения этого запроса будет следующий набор данных (табл. 2.16). Таблица 2.16. Результат выполнения запроса
Первый запрос возвращает строку таблицы Orders, в которой значение поля amount максимально (это строка с id = 1013), второй – строку, в которой значение поля amount минимально (это строка с id = 1012), и при упорядочении по значению столбца id строки меняются местами.
Итак, мы рассмотрели основные возможности поиска и отбора данных, предоставляемые командой SELECT. Далее рассмотрим, как выгружать результат запроса в файл.
Выгрузка данных в файл
Чтобы результат запроса был сохранен в файл, добавьте в команду SELECT выражениеINTO OUTFILE 'Путь и имя файла' [FILEDS …] [LINES …]
В этой команде нужно указать полный путь к файлу, в который будут выгружены данные (этот файл должен быть новым, не существующим на момент выгрузки). При задании пути к файлу необходимо использовать прямую косую черту вместо принятой в Windows обратной косой черты. Указанный файл создается на компьютере, на котором работает сервер MySQL. Данные выгружаются в той кодировке, в которой они хранятся в базе данных.
При необходимости вы можете также задать параметры FILEDS и LINES, которые имеют тот же смысл, что и параметры FILEDS и LINES команды LOAD DATA (см. подраздел «Загрузка данных из файла»). Если впоследствии файл будет загружаться в базу данных MySQL с помощью команды LOAD DATA, то в команде LOAD DATA нужно будет указать те же самые значения параметров FILEDS и LINES, которые использовались при выгрузке.
Команды SELECT… INTO OUTFILE и LOAD DATA можно использовать для резервного копирования таблиц или для переноса данных на другой сервер MySQL. Например, данные из таблицы Customers (Клиенты), сохраненные в файл с помощью командыSELECT * from Customers INTO OUTFILE 'C:/data/Customers.txt
можно загрузить в таблицу Customers_copy (имеющую такую же структуру, что и таблица Customers) с помощью команды
LOAD DATA INFILE 'C:/data/Customers.txt' INTO TABLE Customers_copy;
...Внимание!
В случае выгрузки и последующей загрузки символьных данных в кодировке UTF-8 могут возникнуть проблемы, связанные с переменным количеством байтов на символ в этой кодировке. Если вы выгрузили данные из таблицы с кодировкой UTF-8, рекомендуем перед загрузкой преобразовать файл в какую-либо однобайтовую кодировку. Например, откроем файл с помощью программы Блокнот (Пуск → Все программы → Стандартные → Блокнот), в меню Файл выберите команду Сохранить как, а затем в стандартном окне Windows Сохранить как в поле Кодировка выберите из списка значение «ANSI» и нажмите кнопку Сохранить. При загрузке преобразованного файла укажите в команде LOAD DATA параметр CHARACTER SET cp1251 (см. подраздел «Вставка отдельных строк»).
Итак, вы освоили команду SELECT, которая предоставляет широкие возможности поиска и отбора данных. Последняя операция, которую мы обсудим в этой главе, – редактирование данных в таблицах.
2.6. Изменение данных
В этом разделе вы познакомитесь с командами изменения, замещения и удаления строк таблицы. Начнем с рассмотрения команды UPDATE, которая позволяет установить новые значения в одной или нескольких строках, например, следующим образом:
UPDATE <Имя таблицы>
SET <Имя столбца 1> = <Значение 1>,
…,
<Имя столбца N> = <Значение N>
[WHERE <Условие отбора>]
[ORDER BY <Имя столбца> [ASC или DESC]]
[LIMIT <Количество строк>];Например, если у клиента по фамилии Крылов изменился номер телефона, то обновить информацию в базе данных можно с помощью команды
UPDATE Customers SET phone = '444-25-27' WHERE id = 536;
В команде UPDATE используются следующие основные параметры:
• имя редактируемой таблицы;
• SET <Имя столбца 1> = <Значение 1>, … , <Имя столбца N> = <Знaчение N> – список столбцов и новых значений для этих столбцов. Более подробную информацию о вставке значений в таблицу и о режимах взаимодействия с сервером MySQL вы можете найти в подразделе «Вставка отдельных строк». Задать новое значение вы можете также с помощью выражения, использующего прежние значения в строке. Например, удвоить рейтинги для всех клиентов можно с помощью командыUPDATE Customers SET rating = rating*2;
• WHERE <Условие отбора> – укажите условие отбора, чтобы изменения были применены только к тем строкам таблицы, которые удовлетворяют этому условию. Если условие отбора не задано, изменения будут применены ко всем строкам таблицы. Условия отбора мы рассматривали в подразделе «Условия отбора». В условиях отбора можно использовать вложенный запрос (см. подраздел «Вложенные запросы»), который не должен обращаться к самой модифицируемой таблице.
• ORDER BY <Имя столбца> [ASC или DESC] – при необходимости вы можете указать, в каком порядке применять изменения к строкам таблицы. Обычно порядок применения изменений не влияет на результат выполнения операции. Однако в некоторых случаях последовательность действий может быть важна. Например, если вы установили предельное количество изменяемых строк (см. следующий пункт), то некоторые строки, удовлетворяющие условию отбора, могут остаться неизменными, а какие именно это будут строки – зависит от последовательности применения изменений. Другим подобным случаем является обновление значений первичного ключа или уникального индекса, которые не должны содержать повторяющихся значений, а наличие или отсутствие повторяющихся значений в столбце может зависеть от порядка применения изменений.