Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция 2. SQL. Объединения, подзапросы..docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
35.63 Кб
Скачать

Автор (id, фамилия, имя, телефон, адрес)

authors(au_id, au_fname, au_lname, phone, address, city, country)

Издательство (номер, название издательства, город, страна)

publishers(pub_id, pub_name, city, country)

Книги (id книги, название, жанр (только 1), id издательства, число страниц, стоимость, кол-во проданных книг, дата публикации)

titles (title_id, title_name, type, pub_id, pages, price, sales, pubdate)

Авторы книг (id книги, id автора, порядок автора (с 1))

title_authors (title_id, au_id, au_order)

Подзапросы

Ранее были рассмотрены единичные команды SELECT для работы с одной или несколькими таблицами. В данной лекции будут рассмотрены запросы разных уровней, которые позволяют считывать или изменять данные на основании результатов другого запроса.

Подзапрос – это команда SELECT, встроенная в другую команду SQL. Подзапрос может быть расположен в:

1) предложении SELECT, FROM, WHERE или HAVING другой команды SELECT

2) другом подзапросе

3) команде INSERT, UPDATE или DELETE.

Структура подзапросов такая же, как структура обычной команды SELECT. Отличия:

1) можно поместить подзапрос в предложение SELECT, FROM, WHERE, HAVING или в другой запрос;

2) подзапрос всегда должен заключаться в круглые скобки;

3) нельзя подзапрос точкой с запятой (точкой с запятой необходимо завершить команду, которая включает подзапрос);

4) подзапрос включает одну команду SELECT;

5) подзапрос может использовать столбцы в таблицах, которые приводятся в предложении FROM самого подзапроса или другого подзапроса;

6) если таблица появляется во внутреннем, а не во внешнем запросе, не получится включить столбцы этой таблицы в конечный результат (то есть в предложение SELECT внешнего запроса).

Чаще всего работа происходит с подзапросами в предложении WHERE, которые принимают одну из следующих форм:

- WHERE test_expr op (subquery);

- WHERE test_expr [NOT] IN (subquery);

- WHERE test_expr op ALL (subquery);

- WHERE test_expr op ANY (subquery);

- WHERE [NOT] EXISTS (subquery).

test_expr является буквенным значением, названием столбца, выражением или запросом;

op – это оператор сравнения (=, <>, <, <=, > или >=);

subquery – простой или сложный запрос.

Также можно использовать их в предложении HAVING.

Многие запросы могут быть преобразованы в соединения. Запрос – это лишь способ сгруппировать одну таблицу с другой, не создавая при этом соединения. Поскольку создавать и исполнять подзапросы иногда затруднительно, можно предпочесть им соединения. Однако некоторые задачи можно решить только с помощью подзапросов. Как правило, нет никакой разницы между командой, которая использует подзапрос, и ее эквивалентом, который использует соединение (но бывают и исключения).

На представленные ниже запросы приведены эквивалентные команды, которые используют подзапросы и соединения.

Запрос с использованием в условии оператора IN:

SELECT *

FROM table1

WHERE id IN

(SELECT id FROM table2);

И внутреннее соединение:

SELECT table1.*

FROM table1

INNER JOIN table2

ON table1.id = table2.id;

Следующие три команды тоже эквивалентны (подзапрос NOT IN):

SELECT *

FROM table1

WHERE id NOT IN

(SELECT id FROM table2);

(подзапрос NOT EXISTS):

SELECT table1.*

FROM table1

WHERE NOT EXISTS

(SELECT id FROM table2);

и (внешнее соединение)

SELECT table1.*

FROM table1

LEFT OUTER JOIN table2

ON table1.id = table2.id

WHERE table2.id IS NULL;

Оператор in

Оператор IN рассматривался при рассмотрении предложения WHERE, чтобы сравнивать значение, значение в столбце или выражение со списком значений. Также можно использовать запрос, чтобы создать список.

Параметры при проверке на принадлежность значения множеству, представленному подзапросом:

1) IN работает со значениями в результате запроса так же, как со списком значений;

2) запрос может быть простым или сложным;

3) список столбцов команды SELECT запроса может включать только одно выражение или название столбца;

4) сравниваемые значения должны относиться к одному типу данных или быть конвертируемыми;

5) запрос должен считать одно значение (результат одной строки или столбца). Запрос, который считывает несколько значений, приводит к ошибке.

Проверка на вхождение значения во множество

В предложении WHERE команды SELECT:

WHERE test_expr [NOT] IN (subquery)

test_expr – это буквенное значение, название столбца, выражение или запрос, который возвращает значение;

subquery – запрос, который считывает один столбец и любое количество строк.

Если значение test_expr равно любому значению, полученному с помощью запроса, условие IN задается как истинное.

Условие IN задается как ложное, если результат запроса пустой, ни одна строка

в результате запроса не соответствует test_expr или если все значения в результате запроса равны NULL. Чтобы инвертировать результат условия, укажите NOT.

Предложение HAVING имеет такую же структуру:

HAVING test_expr [NOT] IN (subquery).

Примеры:

1) Отобразить список всех издательств, которые опубликовали биографии.

SELECT pub_name

FROM publishers

WHERE pub_id IN

(SELECT pub_id

FROM titles

WHERE type = 'biography');

2) Отобразить список соавторов, которые живут в Калифорнии и получают менее 50% гонорара за книгу.

SELECT au_id, au_fname, au_lname

FROM authors

WHERE state = 'CA'

AND au_id IN

(SELECT au_id

FROM title_authors

WHERE royalty_share < 0.5

AND au_order > 1);

Оператор IN эквивалентен ключевому слову ANY.

Оператор NOT IN эквивалентен выражению <> ALL (не <> ANY).