Читайте также: |
|
_> WHERE 2 = (SELECT COUNT(*) _> FROM account a
_> WHERE a.cust_id = c.cust_id);
+_________+______________+_________+
| cust_id | cust_type_cd | city |
+_________+______________+_________+
| | | I | | Woburn | | | |||
| | | I | | Quincy | | | |||
| | | I | | Waltham | | ||||
| | | | I | | | Salem | | | |
| | | | B | | | Salem | | |
+_________+______________+_________+ 5 rows in set (0.01 sec)
Ссылка на c.cust_id в самом конце подзапроса – это то, что делает этот подзапрос связанным. Чтобы подзапрос мог выполняться, основной запрос должен поставлять значения для c.cust_id. В данном случае ос_ новной запрос извлекает из таблицы customer все 13 строк и выполняет по одному подзапросу для всех клиентов, передавая в него соответст_
180 Глава 9. Подзапросы
вующий ID клиента при каждом выполнении. Если подзапрос возвра_ щает значение 2, условие фильтрации выполняется и строка добавля_ ется в результирующий набор.
Помимо условий равенства связанные подзапросы можно применять в условиях других типов, таких как условие вхождения в диапазон, проиллюстрированное ниже:
mysql> | SELECT c.cust_id, c.cust_type_cd, c.city | |||
_> | FROM customer c | |||
_> | WHERE (SELECT SUM(a.avail_balance) | |||
_> | FROM account a | |||
_> | WHERE a.cust_id = c.cust_id) | |||
_> | BETWEEN 5000 AND 10000; | |||
+_________+______________+____________+ | ||||
| cust_id | cust_type_cd | city | | | |||
+_________+______________+____________+ | ||||
| | | I | | Waltham | | | |
| | | I | | Wilmington | | ||
| | | B | | Wilmington | |
+_________+______________+____________+ 3 rows in set (0.02 sec)
Этот вариант приведенного ранее запроса находит всех клиентов, чей общий доступный остаток по всем счетам находится в диапазоне от 5000 до 10 000 долларов. И снова связанный подзапрос выполняется 13 раз (по разу для каждой строки), и каждое выполнение подзапроса возвращает общий остаток по счетам данного клиента.
В конце предыдущего раздела было продемонстрировано, как прове_ рять доступный и отложенный остатки счета по транзакциям, зареги_ стрированным по данному счету, и я обещал показать, как изменить пример для обработки всех счетов за одно выполнение. Вот тот пример:
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;
При использовании связанного подзапроса вместо несвязанного основ_ ной запрос может выполняться всего лишь один раз, а подзапрос будет выполняться для каждого счета. Вот обновленная версия:
SELECT CONCAT('ALERT!: Account #', a.account_id, ' Has Incorrect Balance!')
FROM account a
WHERE (a.avail_balance, a.pending_balance) <>
(SELECT SUM(<expression to generate available balance>), SUM(<expression to generate pending balance>)
Связанные подзапросы | |
FROM transaction t
WHERE t.account_id = a.account_id);
Подзапрос теперь включает условие фильтрации, связывающее ID сче_ та транзакции и ID счета из основного запроса. Изменился и блок se_ lect – теперь вместо жестко запрограммированного значения 1 он пу_ тем конкатенации формирует предупреждение, включающее ID счета.
Дата добавления: 2015-08-17; просмотров: 49 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Подзапросы, возвращающие несколько столбцов | | | Оператор exists |