Пример 10: использование группировки данных
Задание 2.1.10.TSK.A: переписать решение 2.1.10.c так, чтобы при подсчёте возвращённых и невозвращённых книг СУБД оперировала исходными значениями поля sb_is_active (т.е. Y и N), а преобразование в «Returned» и «Not returned» происходило после подсчёта.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 65/545
Выборка из нескольких таблиц
2.2. Выборка из нескольких таблиц
2.2.1.Пример 11: запросы на объединение как способ получения человекочитаемых данных
Следующие две задачи уже были упомянуты ранее{14}, сейчас мы рассмотрим их подробно.
Задача 2.2.1.a{67}: показать всю человекочитаемую информацию обо всех книгах (т.е. название, автора, жанр).
Задача 2.2.1.b{69}: показать всю человекочитаемую информацию обо всех обращениях в библиотеку (т.е. имя читателя, название взятой книги).
Ожидаемый результат 2.2.1.a.
b_name |
a_name |
|
g_name |
|
|
|
Евгений Онегин |
А.С. Пушкин |
Классика |
|
|
||
Сказка о рыбаке и рыбке |
А.С. Пушкин |
Классика |
|
|
||
Курс теоретической физики |
Л.Д. Ландау |
Классика |
|
|
||
Курс теоретической физики |
Е.М. Лифшиц |
Классика |
|
|
||
Искусство программирования |
Д. Кнут |
Классика |
|
|
||
Евгений Онегин |
А.С. Пушкин |
Поэзия |
|
|
||
Сказка о рыбаке и рыбке |
А.С. Пушкин |
Поэзия |
|
|
||
Психология программирования |
Д. Карнеги |
Программирование |
|
|||
Психология программирования |
Б. Страуструп |
Программирование |
|
|||
Язык программирования С++ |
Б. Страуструп |
Программирование |
|
|||
Искусство программирования |
Д. Кнут |
Программирование |
|
|||
Психология программирования |
Д. Карнеги |
Психология |
|
|
||
Психология программирования |
Б. Страуструп |
Психология |
|
|
||
Основание и империя |
А. Азимов |
Фантастика |
|
|
||
Ожидаемый результат 2.2.1.b. |
|
|
|
|
|
|
|
|
|
|
|
||
b_name |
s_id |
s_name |
sb_start |
sb_finish |
||
Евгений Онегин |
1 |
Иванов И.И. |
2011-01-12 |
2011-02-12 |
||
Сказка о рыбаке и рыбке |
1 |
Иванов И.И. |
2012-06-11 |
2012-08-11 |
||
Искусство программирования |
1 |
Иванов И.И. |
2014-08-03 |
2014-10-03 |
||
Психология программирования |
1 |
Иванов И.И. |
2015-10-07 |
2015-11-07 |
||
Основание и империя |
1 |
Иванов И.И. |
2011-01-12 |
2011-02-12 |
||
Основание и империя |
3 |
Сидоров С.С. |
2012-05-17 |
2012-07-17 |
||
Язык программирования С++ |
3 |
Сидоров С.С. |
2014-08-03 |
2014-10-03 |
||
Евгений Онегин |
3 |
Сидоров С.С. |
2014-08-03 |
2014-09-03 |
||
Язык программирования С++ |
4 |
Сидоров С.С. |
2012-06-11 |
2012-08-11 |
||
Евгений Онегин |
4 |
Сидоров С.С. |
2015-10-07 |
2015-03-07 |
||
Психология программирования |
4 |
Сидоров С.С. |
2015-10-08 |
2025-11-08 |
||
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 66/545
Пример 11: запросы на объединение как способ получения человекочитаемых данных
Решение 2.2.1.a{66}.
MySQL Решение 2.2.1.a
1SELECT `b_name`,
2`a_name`,
3`g_name`
4 FROM `books`
5JOIN `m2m_books_authors` USING(`b_id`)
6JOIN `authors` USING(`a_id`)
7JOIN `m2m_books_genres` USING(`b_id`)
8JOIN `genres` USING(`g_id`)
MS SQL Решение 2.2.1.a
1SELECT [b_name],
2[a_name],
3[g_name]
4 FROM [books]
5JOIN [m2m_books_authors]
6ON [books].[b_id] = [m2m_books_authors].[b_id]
7JOIN [authors]
8ON [m2m_books_authors].[a_id] = [authors].[a_id]
9JOIN [m2m_books_genres]
10ON [books].[b_id] = [m2m_books_genres].[b_id]
11JOIN [genres]
12ON [m2m_books_genres].[g_id] = [genres].[g_id]
Oracle Решение 2.2.1.a
1SELECT "b_name",
2"a_name",
3"g_name"
4 FROM "books"
5JOIN "m2m_books_authors" USING("b_id")
6JOIN "authors" USING("a_id")
7JOIN "m2m_books_genres" USING("b_id")
8JOIN "genres" USING("g_id")
Ключевое отличие решений для MySQL и Oracle от решения для MS SQL Server заключается в том, что эти две СУБД поддерживают специальный синтаксис указания полей, по которым необходимо производить объединение: если такие поля имеют одинаковое имя в объединяемых таблицах, вместо конструкции ON
первая_таблица.поле = вторая_таблица.поле можно использовать USING(поле), что зачастую очень сильно повышает читаемость запроса.
Несмотря на то, что задача 2.2.1.a является, пожалуй, самым простым случаем использования JOIN, в ней мы объединяем пять таблиц в одном запросе, потому покажем графически на примере одной строки, как формируется финальная выборка.
В рассматриваемых таблицах есть и другие поля, но здесь показаны лишь те, которые представляют интерес в контексте данной задачи.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 67/545
Пример 11: запросы на объединение как способ получения человекочитаемых данных
Первое действие:
[books] JOIN [m2m_books_authors]
ON [books].[b_id] = [m2m_books_authors].[b_id]
Таблица books:
b_id |
b_name |
|
|
1 |
Евгений Онегин |
Таблица m2m_books_authors:
b_id a_id
1 7
Промежуточный результат:
b_id |
b_name |
a_id |
1 |
Евгений Онегин |
7 |
Второе действие:
{результат первого действия} JOIN [authors]
ON [m2m_books_authors].[a_id] = [authors].[a_id]
b_id |
b_name |
a_id |
|
||
1 |
Евгений Онегин |
7 |
|
||
|
|
|
|
||
Таблица |
authors |
: |
|
|
|
|
|
|
|
||
a_id |
|
a_name |
|||
|
|
|
|
||
7 |
А.С. Пушкин |
|
|
||
Промежуточный результат: |
|||||
|
|
|
|||
b_id |
b_name |
a_name |
|||
1 |
Евгений Онегин |
А.С. Пушкин |
|||
Третье действие:
{результат второго действия} JOIN [m2m_books_genres] ON [books].[b_id] = [m2m_books_genres].[b_id]
b_id |
b_name |
a_name |
1 |
Евгений Онегин |
А.С. Пушкин |
Таблица m2m_books_genres:
b_id g_id
1 1
1 5
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 68/545
Пример 11: запросы на объединение как способ получения человекочитаемых данных
Промежуточный результат:
b_name |
a_name |
g_id |
Евгений Онегин |
А.С. Пушкин |
1 |
Евгений Онегин |
А.С. Пушкин |
5 |
Четвёртое действие:
{результат третьего действия} JOIN [genres]
ON [m2m_books_genres].[g_id] = [genres].[g_id]
|
b_name |
a_name |
g_id |
|
|||
Евгений Онегин |
А.С. Пушкин |
1 |
|
||||
Евгений Онегин |
А.С. Пушкин |
5 |
|
||||
|
|
|
|
|
|||
|
Таблица |
genres |
: |
|
|
||
|
|
|
|
|
|
||
|
g_id |
|
g_name |
|
|
||
|
|
|
|
|
|
|
|
1 |
|
Поэзия |
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
Классика |
|
|
|
|
|
|
Итоговый результат: |
|
|
||||
|
|
|
|
||||
|
b_name |
a_name |
g_name |
||||
Евгений Онегин |
А.С. Пушкин |
Поэзия |
|||||
Евгений Онегин |
А.С. Пушкин |
Классика |
|||||
Аналогичная последовательность действий повторяется для каждой строки из таблицы books, что и приводит к ожидаемому результату 2.2.1.a.
Решение 2.2.1.b{66}.
MySQL Решение 2.2.1.b
1SELECT `b_name`,
2`s_id`,
3`s_name`,
4`sb_start`,
5`sb_finish`
6 FROM `books`
7JOIN `subscriptions`
8ON `b_id` = `sb_book`
9JOIN `subscribers`
10ON `sb_subscriber` = `s_id`
MS SQL Решение 2.2.1.b
1SELECT [b_name],
2[s_id],
3[s_name],
4[sb_start],
5[sb_finish]
6 FROM [books]
7JOIN [subscriptions]
8ON [b_id] = [sb_book]
9JOIN [subscribers]
10ON [sb_subscriber] = [s_id]
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 69/545