Читайте также:
|
|
С помощью подзапросов можно как резюмировать имеющиеся данные, так и формировать данные, которых в БД нет ни в какой форме. На_ пример, требуется сгруппировать клиентов по денежным суммам, раз_ мещенным на депозитных счетах, но использовать для этого описания групп, не хранящиеся в БД. Скажем, надо разбить клиентов на сле_ дующие группы:
Группа | Нижний предел | Верхний предел | |
(долларов) | (долларов) | ||
Small | Fry (мелкота) | 4 999,99 | |
Average Joes (середняки) | 5 000 | 9 999,99 | |
Heavy | Hitters (тяжеловесы) | 10 000 | 9 999 999,99 |
Чтобы сформировать эти группы в рамках одного запроса, потребуется способ определения этих трех групп. Первый шаг – создать запрос, формирующий описания групп:
mysql> | SELECT 'Small Fry' name, 0 low_limit, 4999.99 high_limit | |||||
_> | UNION ALL | |||||
_> | SELECT 'Average Joes' name, 5000 low_limit, 9999.99 high_limit | |||||
_> | UNION ALL | |||||
_> SELECT 'Heavy Hitters' | name, 10000 low_limit, 9999999.99 high_limit; | |||||
+_______________+___________+____________+ | ||||||
| name | | low_limit | | high_limit | | ||||
+_______________+___________+____________+ | ||||||
| Small Fry | | | | | 4999.99 | | | ||
| Average Joes | | | | | 9999.99 | | | ||
| Heavy Hitters | | | | 9999999.99 | | |
+_______________+___________+____________+ 3 rows in set (0.00 sec)
Здесь с помощью оператора для работы с наборами union all (объеди_ нить все) результаты трех отдельных запросов сводятся в один резуль_ тирующий набор. Каждый запрос получает три литерала. Результаты этих трех запросов объединяются для формирования таблицы, состоя_ щей из трех строк и трех столбцов. Теперь у нас есть запрос для форми_ рования необходимых групп. Его можно поместить в блок from другого запроса для формирования групп клиентов:
mysql> | SELECT groups.name, COUNT(*) num_customers |
_> | FROM |
_> | (SELECT SUM(a.avail_balance) cust_balance |
Глава 9. Подзапросы | |
_> FROM account a INNER JOIN product p | |
_> | ON a.product_cd = p.product_cd |
_> | WHERE p.product_type_cd = 'ACCOUNT' |
_> | GROUP BY a.cust_id) cust_rollup INNER JOIN |
_> (SELECT 'Small Fry' name, 0 low_limit, 4999.99 high_limit | |
_> | UNION ALL |
_> | SELECT 'Average Joes' name, 5000 low_limit, |
_> | 9999.99 high_limit |
_> | UNION ALL |
_> | SELECT 'Heavy Hitters' name, 10000 low_limit, |
_> | 9999999.99 high_limit) groups |
_> ON cust_rollup.cust_balance | |
_> | BETWEEN groups.low_limit AND groups.high_limit |
_> GROUP BY groups.name;
+_______________+_______________+ | name | num_customers | +_______________+_______________+
| Average Joes | | | | | ||
| | Heavy Hitters | | | | | |
| | Small Fry | | | | |
+_______________+_______________+ 3 rows in set (0.01 sec)
В блоке from имеется два подзапроса: первый подзапрос, cust_rollup, возвращает общий остаток по депозитным счетам для каждого клиента, а второй подзапрос, groups, формирует таблицу, содержащую три груп_ пы клиентов. Вот таблица, сгенерированная подзапросом cust_rollup:
mysql> SELECT SUM(a.avail_balance) cust_balance
_> FROM account a INNER JOIN product p _> ON a.product_cd = p.product_cd
_> WHERE p.product_type_cd = 'ACCOUNT' _> GROUP BY a.cust_id;
+______________+ | cust_balance | +______________+
| | 4557.75 | | |
| | 2458.02 | | |
| | 3270.25 | | |
| | 6788.98 | | |
| | 2237.97 | | |
| | 10122.37 | | |
| | 5000.00 | | |
| | 3875.18 | | |
| | 10971.22 | | |
| | 23575.12 | | |
| | 38552.05 | | |
+______________+ | ||
11 rows in set | (0.05 sec) |
Затем таблица, сгенерированная подзапросом cust_rollup, соединяется с таблицей groups посредством условия вхождения в диапазон (cust_rol_
Использование подзапросов | |
lup.cust_balance BETWEEN groups.low_limit AND groups.high_limit). Нако_ нец, соединенные данные группируются и подсчитывается число кли_ ентов в каждой группе для формирования окончательного результиру_ ющего набора.
Конечно, можно было бы не использовать подзапрос, а просто создать постоянную таблицу для хранения описаний групп. При таком подхо_ де через некоторое время БД изобиловала бы небольшими специаль_ ными таблицами, причины появления которых мало кто помнил бы. Мне приходилось работать в средах, где пользователям БД позволя_ лось создавать собственные таблицы для специальных целей. Резуль_ таты были просто губительными (таблицы, не включенные в резерв_ ные копии; таблицы, потерянные при обновлениях сервера; простои сервера из_за проблем распределения памяти и т. д.). Однако, воору_ жившись запросами, можно придерживаться политики, при которой таблицы добавляются в БД, только если есть очевидная необходимость хранения новых данных.
Дата добавления: 2015-08-17; просмотров: 57 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Использование подзапросов | | | Подзапросы, ориентированные на задачи |