Читайте также:
|
|
До сих пор все примеры подзапросов в данной главе возвращали один столбец и одну или более строк. Однако в определенных ситуациях можно использовать подзапросы, возвращающие два или более столб_ цов. Чтобы лучше разобраться в подзапросах, возвращающих несколь_ ко столбцов, полезно сначала взглянуть на пример использования не_ скольких подзапросов, возвращающих один столбец:
mysql> | SELECT account_id, product_cd, | cust_id | ||||||
_> | FROM account | |||||||
_> | WHERE | open_branch_id | = (SELECT | branch_id | ||||
_> | FROM branch | |||||||
_> | WHERE name = 'Woburn Branch') | |||||||
_> | AND open_emp_id IN (SELECT emp_id | |||||||
_> | FROM employee | |||||||
_> | WHERE | title = 'Teller' OR title = 'Head Teller'); | ||||||
+____________+____________+_________+ | ||||||||
| account_id | product_cd | cust_id | | ||||||||
+____________+____________+_________+ | ||||||||
| | | | CHK | | | | | ||||
| | | | SAV | | | | | ||||
| | | | CD | | | | | ||||
| | | | CHK | | | | | ||||
| | | | SAV | | | | | ||||
| | | | CD | | | | | ||||
| | | | BUS | | | | | ||||
+____________+____________+_________+ | ||||||||
rows in set (0.00 sec) |
Чтобы выявить ID отделения Woburn и ID всех банковских операцио_ нистов, этот запрос использует два подзапроса. Затем содержащий за_ прос использует эту информацию для выбора всех текущих счетов, от_
178 Глава 9. Подзапросы
крытых старшим операционистом в отделении Woburn. Но в таблице employee есть информация об отделении, в котором числится каждый со_ трудник, поэтому те же результаты можно получить путем сравнения столбцов account.open_branch_id и account.open_emp_id с единственным подзапросом к таблицам employee и branch. Для этого в условии фильтра_ ции следует указать в круглых скобках имена обоих столбцов таблицы account в том же порядке, в каком они возвращаются подзапросом:
mysql> | SELECT account_id, product_cd, | cust_id | |||||
_> | FROM account | ||||||
_> | WHERE | (open_branch_id, open_emp_id) IN | |||||
_> | (SELECT b.branch_id, e.emp_id | ||||||
_> | FROM branch b INNER JOIN employee e | ||||||
_> | ON b.branch_id = e.assigned_branch_id | ||||||
_> | WHERE b.name = 'Woburn Branch' | ||||||
_> | AND (e.title = 'Teller' OR | e.title = 'Head Teller')); | |||||
+____________+____________+_________+ | |||||||
| account_id | product_cd | cust_id | | |||||||
+____________+____________+_________+ | |||||||
| | | CHK | | | | | ||||
| | | SAV | | | | | ||||
| | | CD | | | | | ||||
| | | CHK | | | | | ||||
| | | SAV | | | | | ||||
| | | CD | | | | | ||||
| | | BUS | | | | | ||||
+____________+____________+_________+ | |||||||
rows in set (0.00 sec) |
Эта версия запроса делает то же самое, что и предыдущий пример, но с помощью всего одного подзапроса, который возвращает два столбца, а не двух подзапросов, возвращающих по одному столбцу.
Конечно, можно было бы переписать предыдущий пример, просто со_ единив три таблицы, без этой возни с подзапросами. Но при изучении SQL полезно увидеть несколько путей достижения одного результата. Вот еще один пример, требующий применения подзапроса. Скажем, от клиентов поступило несколько жалоб, связанных с неверными зна_ чениями в столбцах доступного остатка и отложенного остатка (pending balance) таблицы account. Задача – найти все счета, остатки на которых не соответствуют суммам по операциям для этого счета. Вот частичное решение проблемы:
SELECT 'ALERT!: Account #1 Has Incorrect Balance!' FROM account
WHERE (avail_balance, pending_balance) <>
(SELECT SUM(<expression to generate available balance>), SUM(<expression to generate pending balance>)
FROM transaction WHERE account_id = 1) AND account_id = 1;
Связанные подзапросы | |
Как видите, здесь нет выражений, суммирующих операции для вычис_ ления доступного и отложенного остатков, но обещаю, что в главе 11, когда мы научимся создавать выражения case, все будет доработано. Но даже в таком виде запрос достаточно полон, чтобы увидеть, что подзапрос генерирует две суммы из таблицы transaction, которые по_ том сравниваются со столбцами avail_balance и pending_balance табли_ цы account. И подзапрос, и основной запрос включают условие фильт_ рации account_id = 1. Таким образом, запрос в его теперешней форме будет проверять только по одному счету за раз. В следующем разделе мы научимся создавать более общую форму запроса, которая будет проверять все счета за одно выполнение.
Дата добавления: 2015-08-17; просмотров: 58 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Оператор any | | | Gt; FROM customer c |