Шаг 9 - Помещение одного запроса внутрь другого
Запросы могут управлять другими запросами. Это делается путем помещения запроса внутрь условия другого запроса и использования вывода внутреннего запроса в верном или неверном условии.
Обычно внутренний запроса генерирует значение, которое проверяется в условии внешнего запроса, определяющего верно оно или нет. Например, мы знаем имя торгового агента - , но не знаем его кода (employeeNumber), и хотим получить все его заказы из таблицы Платежей (Payments).
SELECT customers.customerName,payments.amount
FROM customers,payments
WHERE customers.customerNumber=payments.customerNumber
and customers.salesRepEmployeeNumber=
(SELECT employeeNumber FROM employees
WHERE employees.lastName='Thompson' and employees.firstName='Leslie');
Список заказчиков у агента Thompson
customerName |
amount |
|---|---|
Signal Gift Stores |
14191.12 |
Signal Gift Stores |
32641.98 |
Signal Gift Stores |
33347.88 |
Toys4GrownUps.com |
3879.96 |
Toys4GrownUps.com |
50342.74 |
Toys4GrownUps.com |
39580.6 |
Boards & Toys Co. |
3452.75 |
Boards & Toys Co. |
4465.85 |
Collectable Mini Designs Co. |
80375.24 |
Men R US Retailers, Ltd. |
21053.69 |
Men R US Retailers, Ltd. |
20452.5 |
West Coast Collectables Co. |
7678.25 |
West Coast Collectables Co. |
36070.47 |
Чтобы выполнить внешний (основной запрос), сначала выполняется внутренний запрос
(подзапрос) внутри предложения WHERE. При выполнении подзапроса просматривается
таблица employees, в которой выбираются строки, где поле lastName равно „Thompson“,
затем извлекается значение поля employeeNumber. Единственной строкой будет
employeeNumber = 1166.
Далее полученное значение помещается в условие основного запроса, вместо самого подзапроса, так что условие примет вид:
WHERE salesRepEmployeeNumber = 1166
Основной запрос затем исполняется как обычно со следующими результатами:
customerName |
amount |
|---|---|
Signal Gift Stores |
14191.12 |
Signal Gift Stores |
32641.98 |
При использовании подзапросов в условиях основанных на операциях сравнения (больше, меньше, равно, не равно и т.д.) вы должны убедиться, что подзапрос будет возвращать одно и только значение. Если ваш подзапрос не вернет никакого значения, то основной запрос не выведет никаких значений.
Если Вы хотите использовать подзапрос, который возвращает несколько строк,
то необходимо использовать оператор IN. Как Вы помните, этот оператор
определяет допустимый набор значений, когда он используется с подзапросом этот
список формируется из значений, которые возвращает подзапрос.
Найдем все платежи для агентов из Токио:
SELECT customers.customerName,payments.amount
FROM customers,payments
WHERE customers.customerNumber=payments.customerNumber
AND customers.salesRepEmployeeNumber IN
(SELECT employees.employeeNumber FROM employees,offices
WHERE offices.officeCode=employees.officeCode and offices.city='Tokyo') ;
Результат
+-----------------------------+----------+
| customerName | amount |
+-----------------------------+----------+
| Dragon Souveniers, Ltd. | 44380.15 |
| Dragon Souveniers, Ltd. | 2611.84 |
| Dragon Souveniers, Ltd. | 105743 |
| Dragon Souveniers, Ltd. | 3516.04 |
| Osaka Souveniers Co. | 15183.63 |
| Osaka Souveniers Co. | 47177.59 |
| King Kong Collectables, Co. | 45480.79 |
| Cruz & Sons Co. | 20644.24 |
| Cruz & Sons Co. | 15822.84 |
| Cruz & Sons Co. | 51001.22 |
| Tokyo Collectables, Ltd | 33967.73 |
| Tokyo Collectables, Ltd | 22037.91 |
| Tokyo Collectables, Ltd | 615.45 |
| Tokyo Collectables, Ltd | 48927.64 |
+-----------------------------+----------+