Московский государственный университет имени М.В.Ломоносова
Опубликован: 05.01.2004 | Доступ: свободный | Студентов: 9486 / 1254 | Оценка: 4.04 / 3.84 | Длительность: 10:03:00
ISBN: 978-5-94774-539-9
Лекция 5:

Использование вложенных SQL-запросов

< Лекция 4 || Лекция 5: 123 || Лекция 6 >

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

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

Например:

SELECT * from tbl1 t1
    WHERE f2 IN (SELECT f2 FROM tbl2 t2
                 WHERE t1.f3=t2.f3);

В данном случае для каждой строки таблицы tbl1 будет проверяться условие, что значение поля f2 совпадает со значением строки таблицы tbl2, где значение поля f3 равно значению поля f3 внешней таблицы ( tbl1 ). Это простейший пример коррелированного подзапроса.

Очень часто требуется, чтобы подзапрос использовал те же данные, что и внешняя таблица. В этом случае обязательно применение алиасов.

Например:

SELECT * from tbl1 t_out
    WHERE f2< (SELECT AVG(f2) FROM tbl1 t_in
               WHERE t_out.f1= t_in.f1);

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

Например:

SELECT f1, COUNT(*), SUM(f2) from tbl1 t1
    GROUP BY f1
    HAVING SUM(f2)> (SELECT MIN(f2)*4 
                     FROM tbl1 t1_in
                     WHERE t1.f1=t1_in.f1);

Построение предиката для подзапроса, возвращающего несколько строк

Если в предикате надо сравнить значение с некоторым множеством, то, как было показано выше, можно использовать оператор IN.

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

Например:

SELECT f1,f2,f3 from tbl1
    WHERE EXISTS (SELECT * FROM tbl1 
                  WHERE f4='10/11/2003');

Этот запрос будет формировать не пустой результирующий набор только в том случае, если в какое-либо значение столбца f4 таблицы была занесена дата, например: '10/11/2003'.

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

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

В стандарте SQL-92 не предусмотрено использование в подзапросах, к которым применяется оператор EXISTS агрегирующих функций. Однако некоторые СУБД позволяют такой вид подзапросов.

Для использования результата подзапроса в предикате также применяются операторы ANY и ALL, которые были подробно рассмотрены в предыдущих лекциях.

Приведем пример использования оператора ANY:

SELECT f1,f2,f3 from tbl1
    WHERE f3 = ANY (SELECT f3 FROM tbl2);

Данный оператор определяет, что в результирующий набор будут включены все строки, значение столбца f3 которых присутствует в таблице tbl2.

< Лекция 4 || Лекция 5: 123 || Лекция 6 >