Пример 15: двойное использование условия IN
2.2.5. Пример 15: двойное использование условия IN
Задача 2.2.5.a{98}: показать книги из жанров «Программирование» и/или «Классика» (без использования JOIN; идентификаторы жанров известны).
Задача 2.2.5.b{99}: показать книги из жанров «Программирование» и/или «Классика» (без использования JOIN; идентификаторы жанров неизвестны).
Задача 2.2.5.c{100}: показать книги из жанров «Программирование» и/или «Классика» (с использованием JOIN; идентификаторы жанров известны).
Задача 2.2.5.d{101}: показать книги из жанров «Программирование» и/или «Классика» (с использованием JOIN; идентификаторы жанров неизвестны).
Вариант такого задания, где вместо «и/или» стоит строгое «и», рассмотрен в примере 18{127}.
|
Ожидаемый результат 2.2.5.ab. |
|
|
|
|
b_id |
b_name |
|
1 |
Евгений Онегин |
|
7 |
Искусство программирования |
|
6 |
Курс теоретической физики |
|
4 |
Психология программирования |
|
2 |
Сказка о рыбаке и рыбке |
|
5 |
Язык программирования C++ |
|
|
Ожидаемый результат 2.2.5.С. |
|
b_id |
b_name |
|
1 |
Евгений Онегин |
|
7 |
Искусство программирования |
|
6 |
Курс теоретической физики |
|
4 |
Психология программирования |
|
2 |
Сказка о рыбаке и рыбке |
|
5 |
Язык программирования С++ |
|
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 105/545
Пример 15: двойное использование условия IN
Ожидаемый результат 2.2.5.d.
b_id |
b_name |
1 |
Евгений Онегин |
7 |
Искусство программирования |
6 |
Курс теоретической физики |
4 |
Психология программирования |
2 |
Сказка о рыбаке и рыбке |
5 |
Язык программирования C++ |
уЦ7
Л-/* Решение 2.2.5.a{97}.
Р ^<4
Из таблицы m2m_books_genres можно узнать список идентификаторов книг, относящихся к нужным жанрам, а затем на основе этого списка идентификаторов выбрать из таблицы books названия книг.
MySQL і Решение 2.2.5.a
і |
SELECT 'b |
id' , |
|
|
|
|
2 |
|
'b |
name' |
|
|
|
3 |
FROM |
'books' |
|
|
|
|
4 |
WHERE |
'b |
id' IN (SELECT DISTINCT 'b id' |
|
|
|
5 |
|
|
FROM |
'm2m books genres' |
||
6 |
|
|
WHERE |
'g id' IN ( 2 |
5 |
)) |
7 |
ORDER |
BY |
'b name' ASC |
|
|
|
|
|
|
|
|||
MS SQL І Решение 2.2.5.a |
|
|
|
|||
1 |
SELECT [b |
id] , |
|
|
|
|
2 |
|
[b |
name] |
|
|
|
3 |
FROM |
[books] |
|
|
|
|
4 |
WHERE |
[b |
id] IN (SELECT DISTINCT [b id] |
|
|
|
5 |
|
|
FROM |
[m2m books genres] |
||
6 |
|
|
WHERE |
[g id] IN ( 2 |
5 |
)) |
7 |
ORDER |
BY |
[b name] ASC |
|
|
|
|
|
|
|
|
|
|
|
Oracl |
і |
Решение 2.2.5.a |
| |
|
|
|
|
e |
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
1 |
|
SELECT "b id", |
|
|
|
|
||
2 |
|
|
|
"b name" |
|
|
|
|
3 |
|
FROM |
|
"books" |
|
|
|
|
4 |
|
WHERE |
"b id" IN (SELECT DISTINCT "b id" |
|
||||
5 |
|
|
|
|
FROM |
"m2m books genres" |
||
6 |
|
|
|
|
WHERE |
"g id" IN ( 2 |
5 |
)) |
7 |
|
ORDER BY "bname" |
ASC |
|
|
|
||
Подзапросы в строках 4-6 возвращают следующие значения:
b_id
4_
5_
7__
1_
2_
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 106/545
Пример 15: двойное использование условия IN
Решение 2.2.5.b{97}.
Результат достигается в три шага, на первом из которых по имени жанра определяется его идентификатор с использованием таблицы genres, после чего второй и третий шаги эквивалентны решению 2.2.5.a{98}.
MySQL I |
Решение 2.2.5.b | |
|
|
||||
1 |
SELECT 'b id', |
|
|
||||
2 |
|
|
|
'b name' |
|
|
|
3 |
FROM |
|
'books' |
|
|
||
4 |
WHERE |
'b id' IN (SELECT DISTINCT 'b id' |
|
||||
5 |
|
|
|
|
FROM |
'm2m books genres' |
|
6 |
|
|
|
|
WHERE |
'g id' IN (SELECT 'g id' |
|
|
|
|
|
|
|
FROM |
'genres' |
8 |
|
|
|
|
|
WHERE |
|
9 |
|
|
|
|
|
|
'g_name' IN ( 'Программирование', |
10 |
|
|
|
|
|
|
'Классика' ) |
11 |
|
|
|
|
|
)) |
|
12 |
ORDER BY 'b_name' ASC |
|
|
||||
|
|
|
|
|
|
||
MS SQL |
|
Решение 2.2.5.b |
|
|
|
||
1 |
SELECT |
[b_id], |
|
|
|||
2 |
|
|
|
[b_name] |
|
|
|
3 |
FROM |
|
[books] |
|
|
||
4 |
WHERE |
[b_id] IN (SELECT DISTINCT [b_id] |
|
||||
5 |
|
|
|
|
FROM |
[m2m_books_genres] |
|
6 |
|
|
|
|
WHERE |
[g_id] IN (SELECT [g_id] |
|
|
|
|
|
|
|
FROM |
[genres] |
8 |
|
|
|
|
|
WHERE |
|
9 |
|
|
|
|
|
|
[g_name] IN ( N'Программирование', |
10 |
|
|
|
|
|
|
N'Классика' ) |
11 |
|
|
|
|
|
)) |
|
12 |
ORDER BY [b name] ASC |
|
|
||||
|
|
|
|
|
|
|
|
Oracl |
і |
Решение 2.2.5.b |
I |
|
|
|
|
|
e |
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
1 |
SELECT "b id", |
|
|
|
|
|
||
2 |
|
|
"b name" |
|
|
|
|
|
3 |
FROM |
|
"books" |
|
|
|
|
|
4 |
WHERE |
"b id" IN (SELECT DISTINCT "b id" |
|
|
||||
5 |
|
|
|
|
FROM |
"m2m books genres" |
|
|
6 |
|
|
|
|
WHERE |
"g id" IN (SELECT "g id" |
|
|
7 |
|
|
|
|
|
FROM |
"genres" |
|
8 |
|
|
|
|
|
WHERE |
|
|
9 |
|
|
|
|
|
|
"g_name" IN ( N'Программирование', |
|
10 |
|
|
|
|
|
|
N'Классика' |
) |
11 |
|
|
|
|
|
)) |
|
|
12 |
ORDER BY "b name" |
ASC |
|
|
|
|||
|
Подзапросы 2.2.5.b в строках 6-11 возвращают следующие данные: |
|
||||||
g_id |
|
|
|
|
|
|
|
|
_5 _ |
|
|
|
|
|
|
|
|
2 |
|
|
|
|
|
|
|
|
Подзапросы 2.2.5.b в строках 4-10 возвращают те же данные, что и подзапросы в строках 3-5 решения 2.2.5.а.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 107/545
Пример 15: двойное использование условия IN
Решение 2.2.5.c{97}.
Здесь по-прежнему удобно использовать IN для указания условия выборки, но второе использование IN по условию задачи необходимо заменить на JOIN.
Мы не можем обойтись без ключевого слова DISTINCT, т.к. в противном слу-
чае получим дублирование результатов для книг, относящихся одновременно к обоим требуемым жанрам:
b_id |
b_name |
1 |
Евгений Онегин |
7 |
Искусство программирования |
7 |
Искусство программирования |
6 |
Курс теоретической физики |
4 |
Психология программирования |
2 |
Сказка о рыбаке и рыбке |
5 |
Язык программирования C++ |
Но благодаря тому, что мы помещаем в выборку идентификатор книги, мы не рискуем «схлопнуть» с помощью DISTINCT несколько книг с одинаковыми названиями в одну строку.
Обратите внимание на синтаксические различия этого решения для разных СУБД: MySQL и Oracle не требуют указания на то, из какой таблицы выбирать значение поля b_id (строка 1 запросов 2.2.5.c для MySQL и Oracle), а также поддерживают сокращённую форму указания условия объединения (строка 4 запросов 2.2.5. c для MySQL и Oracle). MS SQL Server требует указывать таблицу, из которой будет происходить извлечение значения поля b_id (строка 1 запроса 2.2.5.c для MS SQL Server), а также не поддерживает сокращённую форму указания условия объединения (строка 5 запроса 2.2.5.c для MS SQL Server).
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 108/545
Пример 15: двойное использование условия IN
Решение 2.2.5.d{97}:
Поскольку первое использование IN по условию задачи пришлось заменить на JOIN, здесь осталось на один уровень IN меньше, чем в решении 2.2.5. b{99}.
Решение 2.2.5.d
1 |
SELECT DISTINCT 'b_id', 'b name' |
|
||||
2 |
|
|
|
|
|
|
3 |
FROM |
'books' |
|
|
|
|
4 |
|
|
JOIN 'm2mbooks genres' USING ( 'b id' ) |
|
||
5 |
WHERE |
'g id' IN(SELECT 'g id' |
|
|||
6 |
|
|
|
FROM |
'genres' |
|
7 |
|
|
|
WHERE |
'g_name' IN ( N'Программирование', |
|
8 |
|
|
|
|
N'Классика' |
) |
9 |
|
|
) |
|
|
|
10 |
ORDER BY 'b name' |
ASC |
|
|
||
|
|
|
|
|
||
MS SQL |
Решение 2.2.5.d |
|
|
|
||
1 |
SELECT DISTINCT [books] |
[b id] |
|
|||
2 |
|
|
[b name] |
|
|
|
3 |
FROM |
[books] |
|
|
|
|
4 |
|
|
JOIN [m2m books genres] |
|
||
5 |
|
|
ON [books] [b id] = [m2m books genres] [b id] |
|||
6 |
WHERE |
[g id] IN |
|
[g id] |
|
|
7 |
|
|
|
FROM |
[genres] |
|
8 |
|
|
|
WHERE [g_name] IN ( ^Программирование', |
||
9 |
|
|
|
|
N'Классика' |
) |
10 |
|
|
|
) |
|
|
11 |
ORDER BY [b name] ASC |
|
|
|||
|
|
|
|
|||
Oracle I Решение 2.2.5.d |
|
|
|
|||
1 |
SELECT DISTINCT "b id", |
|
|
|||
2 |
|
|
"b name" |
|
|
|
3 |
FROM |
"books" |
|
|
|
|
4 |
|
|
JOIN "m2m books genres" USING ( "b id" ) |
|
||
5 |
WHERE |
"g id" IN (SELECT "g id" |
|
|||
6 |
|
|
|
FROM |
"genres" |
|
7 |
|
|
|
WHERE |
"g_name" IN ( ^Программирование', |
|
8 |
|
|
|
|
N'Классика' |
) |
9 |
|
|
|
) |
|
|
10 |
ORDER BY "b name" |
ASC |
|
|
||
|
|
|
|
|
|
|
Логика решения 2.2.5.d является комбинацией 2.2.5. b (по самым глубоко вложенным IN) и 2.2.5.с (по использованию JOIN).
Задание 2.2.5.TSK.A: показать книги, написанные Пушкиным и/или Азимовым (индивидуально или в соавторстве — не важно).
Задание 2.2.5.TSK.B: показать книги, написанные Карнеги и Страустру-
пом в соавторстве.
Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016-2018 Стр: 109/545