Создание
подчиненных запросов
Инструкции Jet SQL, такие как SELECT, SELECT. .. INTO, INSERT...INTO, DELETE или UPDATE позволяют для вычисления предиката в предложении WHERE использовать другой запрос. Этот запрос называется подчиненным запросом.
Подчиненный
запрос включается в главный запрос одним из следующих способов:
где:
сравнение
— выражение и оператор сравнения, который сравнивает это выражение с результатами
подчиненного запроса;
выражение — выражение, для которого проводится поиск в результирующем наборе записей подчиненного запроса;
инструкцияSQL
— инструкция SELECT, которая представляет подчиненный запрос.
Предикаты
ANY или SOME являются синонимами и используются если в главном запросе нужно
выбрать записи, удовлетворяющие сравнению со всеми записями, выбранными в подчиненном
запросе. Ниже приведен пример запроса, который выбирает из таблицы "Товары"
(Products) все товары, цена которых не ниже, чем цена товаров у конкурентов:
SELECT
* FROM Товары WHERE Товары.Цена > ANY
(SELECT
ТоварыКонкурентов.Цена FROM ТоварыКонкурентов)
Предикат ALL
используется для выбора в главном запросе только тех записей, которые удовлетворяют
сравнению со всеми записями, выбранными в подчиненном запросе. В следующем примере
выбираются все заказы, сделанные в 1998 году, стоимость которых ниже стоимости
любого заказа, размещенного в 1997 году:
SELECT DISTINCTROW
Заказы.КодЗаказа
FROM
Заказы
WHERE
Year(Заказы.ДатаРазмещения) = 1998
AND
Заказы.СуммаЗаказа < ALL (SELECT Заказы.СуммаЗаказа FROM Заказы WHERE Year(Заказы.ДатаРазмещения)
= 1997);
Предикат IN
используется для выбора в главном запросе только тех записей, которые содержат
значения, совпадающие с одним из значений, выбранных подчинен-ным_ запросом.
Например, чтобы выбрать клиентов, которые разместили заказы в январе 1998 года,
можно написать следующий запрос:
SELECT * FROM Клиенты WHERE КодКлиента IN
(SELECT
КодКлиента FROM Заказы
WHERE ДатаРазмещения
BETWEEN
#l/l/98# AND #31/1/981;
И наоборот,
предикат NOT IN используется для выбора в главном запросе только тех записей,
которые содержат значения, не совпадающие ни с одним из значений, отобранных
подчиненным запросом.
Предикат EXISTS
используется в логическом выражении для определения того, должен ли подчиненный
запрос возвращать какие-либо записи. Например, чтобы выбрать всех поставщиков
для товаров в некотором заказе, можно использовать следующую инструкцию SQL:
SELECT
DISTINCTROW Поставщики.Название FROM Поставщики WHERE Exists (SELECT Заказано.КодТовара
FROM Заказано
WHERE КодЗаказа
= 121 AND Заказано.КодТовара = Поставщики.КодТовара); В подчиненном запросе
можно-использовать псевдонимы таблиц для ссылки на таблицы, перечисленные в
предложении FROM, расположенном вне подчиненного запроса. В следующем примере
выбираются фамилии и имена сотрудников, чья зарплата равна или больше средней
зарплаты сотрудников, имеющих ту же должность. В предыдущем примере можно присвоить
таблице "Сотрудники" (Employees) псевдоним Т1, и тогда запрос будет
выглядеть следующим образом:
SELECT DISTINCTROW Поставщики.Название
FROM Поставщики As П1
WHERE
Exists
(SELECT Заказано.КодТовара
FROM
Заказано
WHERE КодЗаказа = 121 AND Заказано.КодТовара = П1.КодТовара);
Некоторые
подчиненные запросы можно использовать в перекрестных запросах как предикаты
в предложении WHERE. Подчиненные запросы, применяемые для вывода результатов
(в списке SELECT), нельзя применять в перекрестных запросах.
В отличие
от запросов на объединение, подчиненный запрос можно создать в режиме Конструктора.
В строке
Условия отбора
(Criteria) в качестве условия отбора следует
указать, например, зарезервированное слово IN, а затем ввести инструкцию SELECT.
А можно сначала создать в режиме Конструктора подчиненный запрос, переключиться
в режим SQL, скопировать получившуюся инструкцию SQL в буфер
обмена, а затем создать главный запрос и скопировать в строку Условия отбора (Criteria) подчиненный запрос из буфера.