Читайте также:
|
|
Вы уже посмотрели несколько примеров запросов с тремя таблицами, но хочется особо отметить одну из разновидностей таких запросов. Что делать, если некоторые таблицы формируются подзапросами? Подза_ просам посвящена глава 9, но концепция подзапроса в блоке from уже была представлена в предыдущей главе. Вот другая версия приведен_ ного ранее запроса (выбор всех счетов, открытых опытными операцио_ нистами, в настоящее время работающими в отделении Woburn), в ко_ тором таблица account соединяется с подзапросами к таблицам branch (отделение) и employee:
SELECT a.account_id, a.cust_id, a.open_date, a.product_cd | |
FROM account a INNER JOIN | |
(SELECT emp_id, assigned_branch_id |
4 FROM employee
5 WHERE start_date <= '2003_01_01'
6 AND (title = 'Teller' OR title = 'Head Teller')) e 7 ON a.open_emp_id = e.emp_id
8 INNER JOIN
9 (SELECT branch_id
10 FROM branch
11 WHERE name = 'Woburn Branch') b
12 ON e.assigned_branch_id = b.branch_id;
Первый подзапрос, начинающийся в строке 3 и имеющий псевдоним e, находит всех опытных операционистов. Второй подзапрос, начинаю_ щийся в строке 9 и имеющий псевдоним b, выбирает ID отделения Wo_ burn. Сначала таблица account соединяется с подзапросом по опытным
100 Глава 5. Запрос к нескольким таблицам
операционистам с помощью ID сотрудников, а затем результирующая таблица соединяется с подзапросом по отделению Woburn на основе ID филиала. Результаты аналогичны предыдущей версии запроса (по_ пробуйте и убедитесь сами), но на вид запросы очень отличаются друг от друга.
На самом деле здесь нет ничего необычного, но осознать происходящее можно не сразу. Обратите внимание, например, на отсутствие блока where в основном запросе. Поскольку все условия фильтрации касаются таблиц employee и branch, они находятся в подзапросах. В основном за_ просе никакие условия фильтрации не нужны. Единственный способ проиллюстрировать происходящее – выполнить подзапросы и посмот_ реть на результирующие наборы. Вот результаты выполнения первого подзапроса к таблице employee:
mysql> SELECT emp_id, assigned_branch_id
_> FROM employee | ||||
_> WHERE start_date <= '2003_01_01' | ||||
_> | AND (title = 'Teller' OR title = 'Head Teller'); | |||
+________+____________________+ | ||||
| emp_id | | assigned_branch_id | | |||
+________+____________________+ | ||||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
| | | | | | ||
+________+____________________+ | ||||
rows in set (0.03 sec) |
Таким образом, результирующий набор состоит из набора ID сотруд_ ников и ID соответствующих им отделений. Соединив таблицу account посредством столбца emp_id, имеем промежуточный результирующий набор, содержащий все строки таблицы account и дополнительный столбец с ID отделения, в котором работает сотрудник, открывший каж_ дый из счетов. Вот результаты второго подзапроса к таблице branch:
mysql> SELECT branch_id
_> FROM branch | |
_> WHERE name = 'Woburn Branch'; | |
+___________+ | |
| branch_id | | |
+___________+ | |
| | 2 | |
+___________+
1 row in set (0.02 sec)
Соединение трех и более таблиц | |
По этому запросу возвращается одна_единственная строка с одним столбцом: ID отделения Woburn. Эта таблица соединена со столбцом assigned_branch_id промежуточного результирующего набора, что по_ зволяет отсеять из окончательного результирующего набора все счета, открытые несотрудниками отделения Woburn.
Дата добавления: 2015-08-17; просмотров: 60 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Соединение трех и более таблиц | | | Повторное использование таблицы |