MySQL 5.0. Библиотека программиста
Шрифт:
SELECT name,phone,rating FROM Customers ORDER BY 3 DESC, 1;
Запросы, которые рассматривались в этом подразделе, выводили информацию из всех имеющихся в таблице строк. В следующем подразделе вы узнаете, как использовать запросы для отбора строк таблицы.
Условия отбора
Чтобы выбрать из таблицы строки, удовлетворяющие какому-либо критерию, добавьте в текст запроса выражениеWHERE <Условие отбора>
Например, запрос
SELECT name,phone,rating FROM Customers WHERE rating = 1000;
возвращает только те строки, в которых значение рейтинга равно 1000 (табл. 2.9). Таблица 2.9. Результат выполнения запроса
В
SELECT name,phone,rating FROM Customers
WHERE name LIKE \'ООО%\' OR rating>1000
ORDER BY rating DESC;выводит информацию о тех клиентах, чье имя начинается с «ООО», а также о тех, чей рейтинг превосходит 1000, упорядочивая строки в порядке убывания значения рейтинга (табл. 2.10). Таблица 2.10. Результат выполнения запроса
Пока мы рассматривали запросы, получающие данные только из одной таблицы. В следующем подразделе вы узнаете о запросах, позволяющих выводить информацию сразу из нескольких таблиц.
Объединение таблиц
Получить информацию из нескольких таблиц вы можете, указав в запросе список столбцов и список таблиц, из которых нужно получить информацию:SELECT <Список столбцов> FROM <Список таблиц> WHERE <Условие отбора>;
Например, если требуется вывести информацию о всех заказанных товарах за определенную дату с указанием имен и адресов заказчиков, выполните команду
SELECT name,address,product_id,qty
FROM Customers, Orders
WHERE Customers.id = customer_id AND date = \'2007-12-12\Эта команда выводит следующий результат (табл. 2.11). Таблица 2.11. Результат выполнения запроса
С помощью этого запроса мы получили данные из столбцов name (имя) и address (адрес) таблицы Customers (Клиенты) и столбцов product_id (товар) и qty (кол-во) таблицы Orders (Заказы). Указав условие WHERE Customers. id = customer_id, мы сообщили программе MySQL, что для каждого клиента должны выводиться сведения только о заказах этого клиента. Иначе мы получили бы бессмысленный набор всевозможных комбинаций данных из таблицы Customers с данными из таблицы Orders. Обратите внимание, что столбец с именем id есть и в таблице Customers, и в таблице Orders, поэтому мы добавили имя таблицы Customers в виде префикса к имени столбца.
По такому же принципу можно объединять в запросе и более двух таблиц, и даже таблицу с самой собой. Объединение таблицы с собой можно представить себе как объединение нескольких идентичных таблиц. Чтобы различать эти таблицы, им присваиваются разные псевдонимы. В качестве примера объединения таблицы с самой собой рассмотрим запрос, который выводит всевозможные пары клиентов с одинаковым рейтингом:SELECT L.name,R.name FROM Customers L, Customers R WHERE L.rating = R.rating;
Создавая этот запрос, мы присвоили «первому экземпляру» таблицы Customers псевдоним L, «второму экземпляру» – псевдоним R. В результате объединения «таблиц» мы получили всевозможные пары клиентов: первый клиент в каждой паре – это строка из «таблицы» L, второй – строка из «таблицы» R. С помощью условия WHERE L.rating = R.rating мы выбрали те пары, в которых рейтинг клиента из таблицы L (L.rating) равен рейтингу клиента из таблицы R (R.rating). Как и в предыдущем примере, к именам столбцов мы добавили в виде префикса имена «таблиц» (в данном случае – псевдонимы), чтобы указать, к какому из экземпляров таблицы относится каждый из столбцов.
Таким образом, запрос выводит следующие пары имен (табл. 2.12).
Поскольку наборы строк в «таблицах» L и R одинаковые, в результате запроса появилось много лишних данных: пары одинаковых имен (они возникли при сравнении строки «таблицы» L с точной копией этой строки в «таблице» R), а также одна и та же пара имен сначала в прямом, затем в обратном порядке. Чтобы избавиться от повторений, введите дополнительное условие отбора.
Таблица 2.12. Результат выполнения запросаSELECT L.name,R.name FROM Customers L, Customers R WHERE L.rating = R.rating AND L.name<R.name;
Поскольку
Запросы, объединяющие таблицу с самой собой, можно использовать, в частности, для поиска ошибок дублирования данных в таблице, например для поиска клиентов с разными идентификаторами, но одинаковыми именами, адресами и телефонами.
Далее мы рассмотрим возможности комбинирования запросов.
Вложенные запросы
Результатом запроса является массив данных в виде таблицы, поэтому вы можете использовать результат одного запроса в другом запросе. Во многих случаях вложенными запросами можно заменить объединение таблиц. Например, получить список имен клиентов, когда-либо заказывавших товар № 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. В качестве примера рассмотрим запрос, выводящий информацию о заказах с наибольшей и наименьшей суммой заказа: