Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БД (нет вопросов 9 и 10).docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
3.26 Mб
Скачать

8. Запросы с подзапросами в языке sql, экзистенциальные запросы, подзапросы в операторах манипулирования данными.

Подзапрос - это оператор выбора, который содержится внутри другого оператора выбора, вставки, обновления или удаления, внутри условного оператора или внутри другого подзапроса. Подзапросы обычно содержатся в предложениях where или having SQL оператора или в списке выбора этого оператора. С помощью подзапросов можно проводить дальнейший отбор данных из результатов других запросов. Оператор, содержащий подзапрос, может обрабатывать строки некоторой таблицы, основываясь на результатах вычисления списка выбора подзапроса, который в свою очередь может ссылаться на эту же таблицу как внешний запрос, или обращаться к другой таблице. В языке Transact-SQL подзапросы допускаются почти везде, где допускаются выражения, если подзапрос возвращает одно значение.

Операторы выбора, содержащие один или несколько подзапросов, называются также составными запросами или составными операторами выбора. Возможность включения одного оператора выбора внутрь другого является одной из причин, по которой язык SQL называется “структурированным” (Structured Query Language).

SQL оператор, который включает подзапросы, называемые также внутренними запросами, можно иногда заменить соединением. Есть вопросы, которые можно сформулировать только с помощью подзапросов. Некоторые люди предпочитают всегда использовать подзапросы, поскольку находят их легкими для понимания. Другие стремятся их избегать всегда, когда это возможно. Читатель может выбрать сам удобный для себя способ. (SQL Сервер также переводит некоторые подзапросы в соединения, прежде чем выполнять их).

Если нужно найти все книги, имеющие ту же цену, что и книга Straight Talk About Computers, то это можно сделать за два шага. Во-первых найти цену этой книги:

select price

from titles

where title = "Straight Talk About Computers"

price

-------------

$19.99

(Выбрана 1 строка)

Затем, используя этот результат во втором запросе, уже можно найти все книги, имеющие ту же стоимость, что и Straight Talk:

select title, price

from titles

where price = $19.99

title price

------------------------------------------------------------- --------

The Busy Executive's Database Guide 19.99

Straight Talk About Computers 19.99

Silicon Valley Gastronomic Treats 19.99

Prolonged Data Deprivation: Four Case Studies 19.99

(Выбрано 4 строки)

С помощью подзапроса эта задача решается одним оператором:

select title, price

from titles

where price =

(select price

from titles

where title = "Straight Talk About Computers")

title price

-------------------------------------------------------- --------

The Busy Executive's Database Guide 19.99

Straight Talk About Computers 19.99

Silicon Valley Gastronomic Treats 19.99

Prolonged Data Deprivation: Four Case Studies 19.99

(Выбрано 4 строки)

Общие правила написания и синтаксис подзапросов

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

(select [distinct] список_выбора_подзапроса

[from [[database.]owner.]{название_таблицы | название_вьювера}

[({index название_индекса | prefetch size |[lru|mru]})]}

[holdlock | noholdlock] [shared]

[,[[database.]owner.]{ название_таблицы | название_вьювера }

[({index название_индекса | prefetch size |[lru|mru]})]}

[holdlock | noholdlock] [shared]]... ]

[where условия_отбора]

[group by выражение_без_агрегации [,

выражение_без_агрегации]... ]

[having условия_отбора])

Подзапросы могут быть вложенными в конструкциях (предложениях) where или having внешних операторов выбора (select), вставки (insert), обновления (update) или удаления (delete), а также вложенными в другие подзапросы или помещены в список выбора.

В языке Transact-SQL подзапрос можно помещать почти везде, где допустимы выражения, если этот подзапрос возвращает единственное значение в качестве результата.

Ограничения на подзапросы

На подзапросы накладываются следующие ограничения:

· Подзапросы нельзя использовать в списках предложений order by, group by и compute by.

· Подзапрос не может содержать предложения for browse или union.

· Список выбора внутреннего подзапроса, которому предшествует операция сравнения, может содержать только одно выражение или название столбца, и подзапрос должен возвращать единственный результат. При этом тип данных столбца, указанного в конструкции where внешнего оператора, должен быть совместим c типом данных в столбце, указанным в списке выбора подзапроса (правила здесь такие же как и при соединении).

· В подзапросах не допускаются текстовые (text) и графические (image) данные.

· Подзапросы не могут обрабатывать свои результаты внутренним образом, т.е. подзапрос не может содержать конструкций order by, compute, или ключевого слова into.

· Коррелирующиеся (повторяющиеся) подзапросы не допускаются в конструкции select обновляемого курсора, определенного с помощью declare cursor (определить курсор).

· Количество вложенных уровней для подзапросов не должно превышать 16.

· Максимальное число подзапросов на каждой стороне объединения не больше 16.

Расширенные названия столбцов

В следующем примере столбец pub_id в конструкции where внешнего запроса неявно определяется таблицей publishers из конструкции from этого запроса. Обращение к столбцу pub_id в списке выбора подзапроса определяется конструкцией from подзапроса, т.е. таблицей titles:

select pub_name

from publishers

where pub_id in

(select pub_id

from titles

where type = "business")

Общее правило таково: названия столбцов в операторе неявно определяются таблицей, которая указана в конструкции from этого уровня вложенности.

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

select pub_name

from publishers

where publishers.pub_id in

(select titles.pub_id

from titles

where type = "business")

Никогда нелишне явно указывать название таблицы и всегда можно заменить неявные предположения явным использованием расширенных названий столбцов вместе с названием таблицы.

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

Типы подзапросов

Существуют два основных типа подзапросов:

· Подзапросы, которым предшествует немодифицированная операция сравнения и которые возвращают единственное значение, называются подзапросами- выражениями (скалярными подзапросами).

· Подзапросы, которые возвращают список значений и которым предшествует ключевое слово in (принадлежит) или операция сравнения, модифицированная кванторами any (некоторый) или all (все), а также подзапросы, проверяющие существование с помощью квантора exists (существует), называются квантифицированными предикатными подзапросами.

Подзапросы любого из этих типов могут быть либо коррелированными (повторяющимися), либо некоррелированными.

· Некоррелированный подзапрос может вычисляться как независимый запрос. Иначе говоря, результаты подзапроса подставляются в основной оператор (или внешний запрос). Это не значит, что SQL-сервер именно так выполняет операторы с подзапросами. Некорреляционные подзапросы могут быть заменены соединением и будут выполняться как соединения SQL-сервером.

· Коррелированные подзапросы не могут выполняться как независимые запросы, поскольку они могут обращаться к данным, находящихся в столбцах таблицы, указанной в списке from внешнего запроса. Коррелированные подзапросы детально обсуждаются в конце этой главы.