metBD (1084482), страница 35

Файл №1084482 metBD (Учебное пособие) 35 страницаmetBD (1084482) страница 352018-01-12СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 35)

SELECT S.НОМЕР_ПОСТАВЩИКА

FROM S

WHERE S.ГОРОД != ANY(SELECT P.ГОРОД FROM P);

вовсе не осуществляет выборки номеров поставщиков, находя­щихся в городах, не совпадающих с любыми городами, где хра­нятся детали. Вместо этого оно производит выборку номеров по­ставщиков таких, что город, в котором размещен каждый из них, не совпадает с каким-нибудь городом, где хранятся детали. Экви­валентная формулировка с помощью EXISTS дает ясную кор­ректную интерпретацию:

SELECT S.НОМЕР_ПОСТАВЩИКА

FROM S

WHERE EXISTS (SELECT P.ГОРОД FROM P

WHERE P.ГОРОД != S.ГОРОД);

(«выдать номера поставщиков таких, что существует некоторый город хранения деталей, который отличается от города, где нахо­дится данный поставщик»). Естественная интуитивная интерпре­тация != ANY как «не совпадает с любыми» и некорректна и весьма обманчива. Подобная критика относится ко всем операто­рам, использующим ANY и ALL.

Подзапросы

В этом разделе обсуждаются подзапросы или вложенные пред­ложения SELECT. Говоря нестрого, подзапрос представляет собой выражение SELECT-FROM-WHERE, которое вложено в другое такое предложение. Обычно подзапросы используются для представления множества значений, исследование которых должно осу­ществляться в каком-либо предикате IN, как иллюстрируется в следующем примере.

Простой подзапрос

Выдать фамилии поставщиков, которые поставляют деталь Р2.

SELECT ФАМИЛИЯ

FROM S

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT НОМЕР_ПОСТАВЩИКА

FROM SP

WHERE НОМЕР_ДЕТАЛИ = Р2);

Результат:

ФАМИЛИЯ

Смит

Джонс

Блейк

Кларк

Пояснение. При обработке полного запроса система обрабатывает, прежде всего, вложенный подзапрос. Этот подзапрос воз­вращает множество номеров поставщиков, которые поставляют деталь Р2, а именно множество (’S1’, ’S2’, ’S3’, ’S4’). Поэтому первоначальный запрос эквивалентен следующему простому за­просу:

SELECT ФАМИЛИЯ

FROM S

WHERE НОМЕР_ПОСТАВЩИКА IN

(’S1’, S2, S3, S4);

и, следовательно, получаем приведенный ранее результат.

Неявное уточнение фамилии в этом примере требует дополни­тельного обсуждения. Заметим, в частности, что «НОМЕР_ПОСТАВЩИКА» слева от IN неявным образом уточняется именем таблицы S, в то время как «НОМЕР_ПОСТАВЩИКА» в подза­просе неявно уточняется именем таблицы SP. Справедливо сле­дующее общее правило: предполагается, что неуточненное имя поля должно уточняться именем таблицы (или псевдонимом таб­лицы), указанным в той фразе FROM, которая является непосредственной частью того же са­мого запроса или подзапроса. В случае поля НОМЕР_ПОСТАВ­ЩИКА слева от IN этой фразой является «FROM S», а в случае поля НОМЕР_ПОСТАВЩИКА в подзапросе—это фраза «FROM SP». Для большей ясности повторим первоначальный запрос с явно указанными предполагаемыми уточнениями:

SELECT S.ФАМИЛИЯ

FROM S

WHERE S.НОМЕР_ПОСТАВЩИКА IN

(SELECT SP.НОМЕР_ПОСТАВЩИКА

FROM SP

WHERE SP.НОМЕР_ДЕТАЛИ =P2’);

Неявные уточнения всегда можно отвергнуть путем задания яв­ных уточнений.

Прежде чем перейти к нашему следующему примеру подза­проса, необходимо отметить еще один важный момент. Первона­чальная задача — «Выдать фамилии поставщиков, которые постав­ляют деталь P2» — может быть эквивалентным образом выра­жена как запрос с использованием соединения:

SELECT S.ФАМИЛИЯ

FROM S, SP

WHERE S.НОМЕР_ПОСТАВЩИКА = SP.НОМЕР_ПОСТАВЩИКА

AND SP.НОМЕР_ДЕТАЛИ = P2;

Пояснение. Соединение S и SP по номерам поставщиков пред­ставляет собой таблицу из 12 строк (по одной строке для каждой строки SP), каждая из которых состоит из соответствующей строки SP, дополненной значениями ФАМИЛИЯ, СОСТОЯНИЕ и ГОРОД для поставщика, указываемого значением НОМЕР_ПОСТАВЩИКА в этой строке. Из этих 12 строк только четыре от­носятся к детали P2. Окончательный результат получается, та­ким образом, выделением значения ФАМИЛИЯ из этих четырех строк.

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

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

Выдать фамилии поставщиков, которые поставляют, по край­ней мере, одну красную деталь.

SELECT ФАМИЛИЯ

FROM S

WHERE НОМЕР_ПОСТАВЩИКА IN

(SELECT НОМЕР_ПОСТАВЩИКА

FROM SP

WHERE НОМЕР_ДЕТАЛИ IN

(SELECT НОМЕР_ДЕТАЛИ

FROM Р

WHERE ЦВЕТ = ’Красный’));

Результат:

ФАМИЛИЯ

Смит

Джонс

Кларк

Пояснение. Результатом самого внутреннего подзапроса явля­ется множество (’P1’, ’Р4’, ’Р6’). Подзапрос следующего уровня в свою очередь дает в результате множество (’S1’, ’S2’, ’S4’). Последний, самый внешний SELECT, вычисляет приведенный выше окончательный результат. Вообще допускается любая глу­бина вложенности подзапросов.

Для того чтобы убедиться в Вашем понимании этого примера, попытайтесь выполнить следующие упражнения:

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

  2. Напишите эквивалентную формулировку этого же запроса с использованием соединения.

Коррелированный подзапрос

Выдать фамилии поставщиков, которые поставляют деталь P2. Этот пример уже рассматривался ранее. Однако для иллюст­рации проблемы, рассматриваемой в данном разделе, приведем иное решение этой задачи.

SELECT ФАМИЛИЯ

FROM S

WHERE P2’ IN

(SELECT НОМЕР_ДЕТАЛИ

FROM SP

WHERE НОМЕР_ПОСТАВЩИКА =

S.НОМЕР_ПОСТАВЩИКА);

Пояснение. В последней строке приведенного запроса неуточненная ссылка на НОМЕР_ПОСТАВЩИКА уточняется неявным образом именем таблицы SP. Другая ссылка явно уточняется именем таблицы S. Этот пример отличается от предыдущих тем, что внутренний подзапрос не может быть обработан прежде, чем будет обрабатываться внешний запрос, поскольку этот внутренний подзапрос зависит от переменной, а именно от S.HOMEP_ПОСТАВЩИКА, значение которой изменяется по мере того, как система проверяет различные строки таблицы S. Сле­довательно, с концептуальной точки зрения обработка осуществ­ляется следующим образом.

  1. Система проверяет первую строку таблицы S. Предположим, что это строка поставщика «S1». Тогда переменная S.HOMEP_ПОСТАВЩИКА в данный момент имеет значение ’S1’, и си­стема обрабатывает внутренний запрос

(SELECT НОМЕР_ДЕТАЛИ

FROM SP

WHERE НОМЕР_ДЕТАЛИ = ’S1’),

получая в результате множество (’Р1’, ’P2’, ’Р3’, ’Р4’, ’Р5’, ’Р6’). Теперь она может завершить обработку для S1. Выборка значе­ния ФАМИЛИЯ для S1, а именно Смит, будет произведена тогда и только тогда, когда ’Р2’ принадлежит этому множеству, что, очевидно, справедливо.

  1. Далее система будет повторять обработку такого рода для следующего поставщика и т.д. до тех пор, пока не будут рассмотрены все строки таблицы S.

Такой подзапрос, как в этом примере, называется коррелиро­ванным. Коррелированный подзапрос — это такой подзапрос, ре­зультат которого зависит от некоторой переменной. Эта перемен­ная принимает свое значение в некотором внешнем запросе. Об­работка такого подзапроса, следовательно, должна повторяться для каждого значения переменной в запросе, а не выполняться раз навсегда. Далее будет приведен другой пример коррелиро­ванного подзапроса.

Для того чтобы сделать более ясной связь коррелированных подзапросов с внешними запросами, некоторые пользователи лю­бят вводить псевдонимы. На­пример:

SELECT SX.ФАМИЛИЯ

FROM S SX

WHERE ’Р2’ IN

(SELECT НОМЕР_ДЕТАЛИ

FROM SP

WHERE НОМЕР_ПОСТАВЩИКА =

SX.НОМЕР_ПОСТАВЩИКА);

В этом примере псевдонимом является имя SX, введенное во фразе FROM как альтернативное имя таблицы S и используемое далее в качестве явного уточнителя во фразе WHERE подза­проса, а также во фразе SELECT внешнего запроса. Действие приведенного выше полного предложения можно теперь описать более понятно и более точно следующим образом:

  • SX — это переменная, областью определения которой является множество записей таблицы S, т. е. переменная, представляю­щая в любой заданный момент времени некоторую запись таб­лицы S.

  • Поочередно для каждого возможного значения SX выполнить следующее:

  • вычислить подзапрос и получить множество номеров де­талей, например Р;

  • добавить к результирующему множеству значение SX.ФА­МИЛИЯ, если и только если Р2 принадлежит множеству Р.

В предыдущем варианте, этого запроса символ «S» в действи­тельности выполнял две различные функции. Он обозначал, ко­нечно, саму базовую таблицу, а также переменную, которая опре­делена на множестве записей этой базовой таблицы. Как уже указывалось, многие считают более ясным использование двух различных символов для того, чтобы различать эти две различные функции.

Введение псевдонима никогда не является ошибкой, а иногда оно необходимо.

Случай использования одной и той же таблицы в подзапросе и внешнем запросе

Выдать номера поставщиков, которые поставляют, по крайней мере, одну деталь, поставляемую поставщиком S2.

SELECT DISTINCT НОМЕР_ПОСТАВЩИКА

FROM SP

WHERE НОМЕР_ДЕТАЛИ IN

(SELECT НОМЕР_ДЕТАЛИ

FROM SP

WHERE НОМЕР_ПОСТАВЩИКА = S2);

Результат:

НОМЕР_ПОСТАВЩИКА

S1

S2

S3

S4

Отметим здесь, что ссылка на SP в подзапросе означает не то же самое, что ссылка на SP во внешнем запросе. В действи­тельности, два имени SP обозначают различные переменные. Чтобы этот факт стал явным, можно использовать псевдонимы:

SELECT DISTINCT SPX.НОМЕР_ПОСТАВЩИКА

FROM SP SPX

WHERE SPX.НОМЕР_ДЕТАЛИ IN

(SELECT SPY.НОМЕР_ДЕТАЛИ

FROM SP SPY

WHERE SPY.НОМЕР_ПОСТАВЩИКА = ’S2’);

Эквивалентный запрос с использованием соединения имеет вид:

SELECT DISTINCT SPX.НОМЕР_ПОСТАВЩИКА

FROM SP SPX, SP SPY

WHERE SPX.НОМЕР_ДЕТАЛИ = SPY.НОМЕР_ДЕТАЛИ

AND SPY.НОМЕР_ПОСТАВЩИКА = S2;

Случай, когда в коррелированном и внешнем запросе используется одна и та же таблица

Выдать номера всех деталей, поставляемых более чем одним поставщиком:

SELECT DISTINCT SPX.НОМЕР_ДЕТАЛИ

FROM SP SPX

WHERE SPX.НОМЕР_ДЕТАЛИ IN

Характеристики

Тип файла
Документ
Размер
1,9 Mb
Тип материала
Предмет
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6294
Авторов
на СтудИзбе
314
Средний доход
с одного платного файла
Обучение Подробнее