Материал: Using_MySql,_MS_SQL_Server_and_Oracle(1)

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Пример 14: нетривиальные случаи использования условия IN и запросов на объединение

Таким образом, Иванов И.И. оказывается пропущенным. Поэтому нужно использовать решение, представленное в начале рассмотрения задачи 2.2.4.a (т.е. решение с преобразованием значения поля sb_is_active).

Решение 2.2.4.b{92}.

MySQL Решение 2.2.4.b

1SELECT `s_id`,

2`s_name`

3

 

FROM

`subscribers`

 

 

4

 

WHERE

`s_id` NOT IN

(SELECT

DISTINCT `sb_subscriber`

5

 

 

 

FROM

`subscriptions`

6

 

 

 

WHERE

`sb_is_active` = 'Y')

MS SQL Решение 2.2.4.b

1SELECT [s_id],

2[s_name]

3

 

FROM

[subscribers]

 

 

4

 

WHERE

[s_id] NOT IN

(SELECT

DISTINCT [sb_subscriber]

5

 

 

 

FROM

[subscriptions]

6

 

 

 

WHERE

[sb_is_active] = 'Y')

 

 

 

 

 

 

Oracle Решение 2.2.4.b

1SELECT "s_id",

2"s_name"

3

 

FROM

"subscribers"

 

 

4

 

WHERE

"s_id" NOT IN

(SELECT

DISTINCT "sb_subscriber"

5

 

 

 

FROM

"subscriptions"

6

 

 

 

WHERE

"sb_is_active" = 'Y')

Типичной ошибкой при решении задачи 2.2.4.b является попытка получить нужный результат следующим запросом:

MySQL

Решение 2.2.4.b (ошибочный запрос)

1SELECT `s_id`,

2`s_name`

 

3

 

FROM

`subscribers`

 

 

4

 

WHERE

`s_id` IN (SELECT

DISTINCT `sb_subscriber`

 

5

 

 

 

FROM

`subscriptions`

 

6

 

 

 

WHERE

`sb_is_active` = 'N')

 

 

 

Решение 2.2.4.b (ошибочный запрос)

 

MS SQL

 

1SELECT [s_id],

2[s_name]

 

3

 

FROM

[subscribers]

 

 

4

 

WHERE

[s_id] IN (SELECT

DISTINCT [sb_subscriber]

 

5

 

 

 

FROM

[subscriptions]

 

6

 

 

 

WHERE

[sb_is_active] = 'N')

 

 

 

 

Решение 2.2.4.b (ошибочный запрос)

 

Oracle

 

 

1SELECT "s_id",

2"s_name"

 

3

 

FROM

"subscribers"

 

 

4

 

WHERE

"s_id" IN (SELECT

DISTINCT "sb_subscriber"

 

5

 

 

 

FROM

"subscriptions"

 

6

 

 

 

WHERE

"sb_is_active" = 'N')

 

 

 

Получается такой набор данных:

 

 

 

 

s_id

s_name

 

 

1

 

Иванов И.И.

 

 

4

 

Сидоров С.С.

 

 

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 95/545

Пример 14: нетривиальные случаи использования условия IN и запросов на объединение

Но это — решение задачи «показать читателей, которые хотя бы раз вернули книгу». Данная проблема (характерная для многих подобных ситуаций) лежит не столько в области правильности составления запросов, сколько в области понимания смысла (семантики) модели базы данных.

Если по некоторому факту выдачи книги отмечено, что она возвращена (в поле sb_is_active стоит значение N), это совершенно не означает, что рядом нет другого факта выдачи тому же читателю книги, которую он ещё не вернул. Рассмотрим это на примере читателя с идентификатором 4 («Сидоров С.С.»):

sb_id

sb_subscriber

sb_book

sb_start

sb_finish

sb_is_active

57

 

 

 

 

N

4

5

2012-06-11

2012-08-11

91

 

 

 

 

Y

4

1

2015-10-07

2015-03-07

99

 

 

 

 

Y

4

4

2015-10-08

2025-11-08

Он вернул одну книгу, и потому подзапрос вернёт его идентификатор, но ещё две книги он не вернул, и потому по условию исходной задачи он не должен оказаться в списке.

Также очевидно, что читатели, никогда не бравшие книг, не попадут в список людей, у которых на руках нет книг (идентификаторы таких читателей вообще ни разу не встречаются в таблице subscriptions).

Задание 2.2.4.TSK.A: показать список книг, ни один экземпляр которых сейчас не находится на руках у читателей.

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 96/545

Пример 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.a.

 

 

b_id

b_name

1

Евгений Онегин

7

Искусство программирования

6

Курс теоретической физики

4

Психология программирования

2

Сказка о рыбаке и рыбке

5

Язык программирования С++

 

Ожидаемый результат 2.2.5.b.

 

 

b_id

b_name

1

Евгений Онегин

7

Искусство программирования

6

Курс теоретической физики

4

Психология программирования

2

Сказка о рыбаке и рыбке

5

Язык программирования С++

 

Ожидаемый результат 2.2.5.c.

 

 

b_id

b_name

1

Евгений Онегин

7

Искусство программирования

6

Курс теоретической физики

4

Психология программирования

2

Сказка о рыбаке и рыбке

5

Язык программирования С++

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 97/545

Пример 15: двойное использование условия IN

 

Ожидаемый результат 2.2.5.d.

 

 

b_id

b_name

1

Евгений Онегин

7

Искусство программирования

6

Курс теоретической физики

4

Психология программирования

2

Сказка о рыбаке и рыбке

5

Язык программирования С++

Решение 2.2.5.a{97}.

Из таблицы m2m_books_genres можно узнать список идентификаторов книг, относящихся к нужным жанрам, а затем на основе этого списка идентификаторов выбрать из таблицы books названия книг.

MySQL Решение 2.2.5.a

1SELECT `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

1SELECT [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

 

Oracle Решение 2.2.5.a

1SELECT "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

 

 

 

 

 

 

Подзапросы в строках 4-6 возвращают следующие значения:

b_id

4

5

7

1

2

6

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 98/545

Пример 15: двойное использование условия IN

Решение 2.2.5.b{97}.

Результат достигается в три шага, на первом из которых по имени жанра определяется его идентификатор с использованием таблицы genres, после чего второй и третий шаги эквивалентны решению 2.2.5.a{98}.

MySQL Решение 2.2.5.b

1SELECT `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 ( 'Программирование',

10

 

 

 

 

'Классика' )

 

 

 

 

 

 

11

 

 

 

))

 

12

 

ORDER

BY `b_name` ASC

 

 

MS SQL Решение 2.2.5.b

1SELECT [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

 

 

Oracle Решение 2.2.5.b

1SELECT "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.a.

Работа с MySQL, MS SQL Server и Oracle в примерах © EPAM Systems, RD Dep, 2016–2018 Стр: 99/545

Источник: https://studfile.net/preview/16418462/