Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по Базам данных » MSSQL - Все статьи »

Обсудить на форуме Обсудить на форуме

Помещение одного запроса внутрь другого.

Запросы могут управлять другими запросами. Это делается путем помещения запроса внутрь условия другого запроса и использования вывода внутреннего запроса в верном или неверном условии.

Обычно внутренний запроса генерирует значение, которое проверяется в условии внешнего запроса, определяющего верно оно или нет. Например, мы знаем имя торгового агента - Сидоров, но не знаем его кода (snum), и хотим получить все его заказы из таблицы Заказов (Orders).

SELECT * 
FROM Orders
WHERE snum = (
	SELECT snum
	FROM Salespeople
	WHERE sname = 'Сидоров'
)
Чтобы выполнить внешний (основной запрос), сначала выполняется внутренний запрос (подзапрос) внутри предложения WHERE. При выполнении подзапроса просматривается таблица Salespeople, в которой выбираются строки, где поле sname равно 'Иванов', затем извлекается значение поля snum. Единственной строкой будет snum = 1004. Далее полученное значение помещается в условие основного запроса, вместо самого подзапроса, так что условие примет вид:
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 = 'Москва'
Хотя этот запрос эквивателнтен предыдущему, SQL Server должен будет просмотреть каждую возможную комбинацию строк из двух таблиц и проверить их соответствие условию. Проще и эффективнее просто извлечь из таблицы Торговых агентов их коды и затем искать их в таблице Заказов. На самом деле выигрыша в производительности может не быть за счет того, что оптимизатор запросов, встроенный в SQL Server, преобразует последний запрос в форму с подзапросом.

Все вышеприведенные подзапросы объединяет то, что все они выбирают один единственный столбец. Это обязательно поскольку их результат сравнивается с одиночным значением. Команды типа 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

Теперь вы имеет представление об использовании вложенных подзапросов. Этот механизм позволяет расширить возможности по отбору данных.


Может пригодится:


Автор:
Прочитано: 2858
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру