Запросы могут управлять другими запросами. Это делается путем помещения запроса внутрь условия другого запроса и использования вывода внутреннего запроса в верном или неверном условии.
Обычно внутренний запроса генерирует значение, которое проверяется в условии внешнего запроса, определяющего верно оно или нет. Например, мы знаем имя торгового агента - Сидоров, но не знаем его кода (snum), и хотим получить все его заказы из таблицы Заказов (Orders).
SELECT * FROM Orders WHERE snum = ( SELECT snum FROM Salespeople WHERE sname = 'Сидоров' )
WHERE snum = 1004
ONUM ODATE AMT CNUM SNUM ----- ------------------------ ---------- ------ ----- 3002 1999-10-03 00:00:00.000 1900.1000 2007 1004
При использовании подзапросов в условиях основанных на операциях сравнения (больше, меньше, равно, не равно и т.д.) вы должны убедиться, что подзапрос будет возвращать одно и только значение. Если ваш подзапрос не вернет никакого значения, то основной запрос не выведет никаких значений.
Если Вы хотите использовать подзапрос, который возвращает несколько строк, то необходимо использовать оператор IN. Как Вы помните, этот оператор определяет допустимый набор значений, когда он используется с подзапросом этот список формируется из значений, которые возвращает подзапрос. Найдем все заказы для агента из Москвы:
SELECT * FROM Orders WHERE snum IN ( SELECT snum FROM Salespeople WHERE city = 'Москва' )Результат:
ONUM ODATE AMT CNUM SNUM ----- ------------------------ ---------- ----- ----- 3003 1999-10-03 00:00:00.000 767.1900 2001 1001 3008 1999-10-05 00:00:00.000 4723.0000 2006 1001 3011 1999-10-06 00:00:00.000 9891.8800 2006 1001
SELECT Orders.* FROM Orders, Salespeople WHERE Orders.snum = Salespeople.snum AND Salespeople.city = 'Москва'
Все вышеприведенные подзапросы объединяет то, что все они выбирают один единственный столбец. Это обязательно поскольку их результат сравнивается с одиночным значением. Команды типа SELECT * запрещены в подзапросах.
Подзапросы можно также использовать в предложении HAVING. Эти подзапросы могут использовать собственные предложения GROUP BY или HAVING. Следующий запрос является тому примером:
SELECT rating, COUNT( DISTINCT cnum ) FROM Customers GROUP BY rating HAVING rating > ( SELECT AVG( rating ) FROM Customers WHERE city = 'Москва' )
Эта команда подсчитывает заказчиков с рейтингом выше среднего в Москве. Результат:
rating ------- -- 200 2 300 2
Теперь вы имеет представление об использовании вложенных подзапросов. Этот механизм позволяет расширить возможности по отбору данных.