Оператор SELECT. Выбор данных из таблицы. Псевдонимы столбцов. Удаление повторяющихся строк, страница 12

Эквивалентные запросы:

SELECT *

FROM table1

WHERE id NOT IN (SELECT id FROM table2);

SELECT table1.*

FROM table1

WHERE NOT EXIST (SELECT id FROM table2);

SELECT table1.*

FROM table1

LEFT JOIN table2

ON table1.id = table2.id

WHERE table2.id IS NULL;

Пример. Авторы, которые не участвовали в написании опубликованных книг. (запрос NOT-in-List-Authors)

1) SELECT au_id, au_fname, au_lname

FROM authors

WHERE au_id NOT IN (SELECT au_id FROM title_authors);

2) SELECT au_id, au_fname, au_lname

FROM authors a

WHERE NOT EXISTS

(SELECT *

FROM title_authors ta

WHERE a.au_id = ta.au_id);

3) SELECT a.au_id, a.au_fname, a.au_lname

FROM authors a

LEFT JOIN title_authors ta

ON  a.au_id = ta.au_id

WHERE ta.au_id IS NULL;

Подзапросы применяют, если требуется сравнение с результатом агрегатной функции (среднее, максимум…). Если требуется включить в запрос столбцы из нескольких таблиц применяется объединение таблиц (нельзя включить столбцы из таблицы внутреннего запроса).

Простые подзапросы

Простой подзапрос – запрос, который может рассматриваться независимо от внешнего и обрабатывается только один раз.

СУБД выполняет внутренний запрос один раз, затем помещает результат во внешний запрос. Внутренний запрос выполняется до и независимо от внешнего запроса.

Пример. Список авторов, которые живут в городах, где располагаются издательства. (запрос Authors-Publishers#City)

SELECT au_id, city

FROM authors

WHERE city IN

(SELECT city FROM publisher);

Внутренний запрос формирует список городов, где расположены издательства. Внешний использует список в условии отбора строк.

Сложные подзапросы

Сложные запросы отличаются более сложным механизмом исполнения. Сложный подзапрос:

- отличается порядком и количеством исполнений;

- не может быть исполнен отдельно, поскольку зависит от внешнего запроса;

- исполняется для каждой строки, выбранной внешним запросом;

всегда обращается к таблице, указанной в предложении FROM внешнего запроса;

- ссылается на столбцы внешнего запроса, которые называются корреляционными переменными.

Структура сложного запроса:

SELECT внешние_столбцы

FROM внешняя_таблица

WHERE значение_внешнего_столбца IN

(SELECT внутренний_столбец

FROM внутренняя_таблица

WHERE внутренний_столбец = внешний_столбец);

Исполнение начинается с внешнего запроса, который выбирает каждую строку внешней таблицы и выполняет внутренний запрос, выбирая строки внутренней таблицы. Для отобранных строк внутренней таблицы проверяется условие внешнего запроса. Процесс продолжается для всех строк внешней таблицы.

Пример. Список книг, уровень продаж которых выше среднего уровня для книг соответствующего типа. (запрос ComplexSUB-List-AVG#Sales)

SELECT

candidate.title_id, candidate.type, candidate.sales

FROM title candidate

WHERE sales >=

(SELECT AVG(sales)

FROM title average

WHERE average.type = candidate.type);

Внутренний подзапрос нельзя выполнить отдельно, поскольку необходимо значение корреляционной переменной candidate.type. Для строки внешней таблицы внутренний запрос рассчитывает средний уровень продаж соответствующего типа (тип книги берется из строки таблицы candidate). Затем внешний запрос сравнивает эту величину со строкой внешней таблицы (значение столбца sales сравнивается со средним). Если продажи выше, значения столбцов строки будут помещены в результат запроса. Далее все повторяется для каждой строки внешней таблицы.

Примечание. Если результат может быть получен как с помощью простого, так и сложного запросов, рекомендуется выбирать простой, поскольку он выполняется быстрее.

Подзапросы в качестве выражений в списке столбцов

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

Пример. Список книг, цена, средняя цена книг. (запрос SELECT-SUB)

SELECT