RSS    

   Реферат: Организация Web-доступа к базам данных с использованием SQL-запросов

SELECT  Название, Статус

FROM    Поставщики

WHERE   ПС IN (1, 5, 6, 8);

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

SELECT  Название, Статус

FROM    Поставщики

WHERE   ПС IN

        (       SELECT  ПС

                FROM    Поставки

                WHERE   ПР IN

                        (       SELECT  ПР

                                FROM    Продукты

                                WHERE   Продукт = 'Помидоры' ));

В данном случае результатом самого внутреннего подзапроса является только одно значение (11). Как уже было показано выше, подзапрос следующего уровня в свою очередь дает в результате множество (1, 5, 6, 8). Последний, самый внешний SELECT, вычисляет приведенный выше окончательный результат. Вообще допускается любая глубина вложенности подзапросов.

Тот же результат можно получить с помощью соединения

SELECT  Название, Статус

FROM    Поставщики, Поставки, Продукты

WHERE   Поставщики.ПС = Поставки.ПС

AND     Поставки.ПР = Продукты.ПР

AND     Продукт = 'Помидоры';

При выполнении этого компактного запроса система должна одновременно обрабатывать данные из трех таблиц, тогда как в предыдущем примере эти таблицы обрабатываются поочередно. Естественно, что для их реализации тебуются различные ресурсы памяти и времени, однако этого невозможно ощутить при работе с ограниченным объемом данных в иллюстративной базе ПАНСИОН.

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

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

Результат:

SELECT       DISTINCT ПС

FROM         Поставки

WHERE        ПР IN

             (            SELECT       ПР

                          FROM         Поставки

                          WHERE        ПС = 6);

ПС

1
3
5
6
8

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

SELECT  DISTINCT X.ПС

FROM    Поставки X

WHERE   X.ПР IN

        (       SELECT  Y.ПР

                FROM    Поставки Y

                WHERE   Y.ПС = 6 );

Здесь X и Y – произвольные псевдонимы таблицы Поставки, определяемые во фразе FROM и используемые как явные уточнители во фразах SELECT и WHERE. Напомним, что псевдонимы определены лишь в пределах одного запроса.

Вложенный подзапрос с оператором сравнения, отличным от IN

Выдать номера поставщиков, находящихся в том же городе, что и поставщик с номером 6.

Результат:

SELECT       ПС

FROM         Поставщики

WHERE        Город =     

             (            SELECT       Город

                          FROM         Поставщики

                          WHERE        ПС = 6 );   

ПС

1
4
6

В подобных запросах можно использовать и другие операторы сравнения (<, <=, <, = или ), однако, если вложенный подзапрос возвращает более одного значения и не используется оператор IN, будет возникать ошибка.

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

Выдать название и статус поставщиков продукта с номером 11.

SELECT  Название, Статус

FROM    Поставщики

WHERE   11 IN

        (       SELECT  ПР

                FROM    Поставки

                WHERE   ПС = Поставщики.ПС );

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

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

( SELECT  ПР

  FROM    Поставки

  WHERE   ПС = 1 );

получая в результате множество (9, 11, 12, 15). Теперь система может завершить обработку для поставщика с номером 1. Выборка значений Название и Статус для ПС=1 (СЫТНЫЙ и рынок) будет проведена тогда и только тогда, когда ПР=11 будет принадлежать этому множеству, что, очевидно, справедливо.

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

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

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

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

Результат:

SELECT       DISTINCT X.ПР

FROM         Поставки X

WHERE        X.ПР NOT IN

             (            SELECT       Y.ПР        

                          FROM         Поставки Y  

                          WHERE        Y.ПС <> X.ПС );

X.ПР

17

            Действие этого запроса можно пояснить следующим образом: «Поочередно для каждой строки таблицы Поставки, скажем X, выделить значение номера продукта (ПР), если и только если это значение не входит в некоторую строку, скажем, Y, той же таблицы, а значение столбца номер поставщика (ПС) в строке Y не равно его значению в строке X».

            Отметим, что в этой формулировке должен быть использован по крайней мере один псевдоним – либо X, либо Y.

Запросы, использующие EXISTS

Квантор EXISTS (существует) – понятие, заимствованное из формальной логики. В языке SQL предикат с квантором существования представляется выражением EXISTS (SELECT * FROM …).

Такое выражение считается истинным только тогда, когда результат вычисления «SELECT * FROM …» является непустым множеством, т.е. когда существует какая-либо запись в таблице, указанной во фразе FROM подзапроса, которая удовлетворяет условию WHERE подзапроса. (Практически этот подзапрос всегда будет коррелированным множеством.)

Рассмотрим примеры. Выдать названия поставщиков, поставляющих продукт с номером 11.

Результат:

  SELECT     Название

FROM         Поставщики

WHERE        EXISTS

             (            SELECT       *

                          FROM         Поставки

                          WHERE        ПС = Поставщики.ПС

                          AND          ПР = 11 );

Название

СЫТНЫЙ
УРОЖАЙ
КОРЮШКА
ЛЕТО

Система последовательно выбирает строки таблицы Поставщики, выделяет из них значения столбцов Название и ПС, а затем проверяет, является ли истинным условие существования, т.е. су-ществует ли в таблице Поставки хотя бы одна строка со значением ПР=11 и значением ПС, равным значению ПС, выбранному из таблицы Поставщики. Если условие выполняется, то полученное значение столбца Название включается в результат.

Предположим, что первые значения полей Название и ПС равны, соответственно, 'СЫТНЫЙ' и 1. Так как в таблице Поставки есть строка с ПР=11 и ПС=1, то значение 'СЫТНЫЙ' должно быть включено в результат.

Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24


Новости


Быстрый поиск

Группа вКонтакте: новости

Пока нет

Новости в Twitter и Facebook

                   

Новости

© 2010.