Использование вложенных запросов
Здесь надо сказать о двух моментах.
- В этом запросе имеются два уровня вложенности. Два подзапроса – это в точности оператор предыдущего запроса. Теперь он вложен во внешний замыкающий оператор SELECT. Он принимает список товаров, в состав которых входят мониторы. Перед SELECT стоит другое ключевое слово – NOT EM. В результате действия внешнего оператора создается еще один список. В нем перечислены модели всех продуктов, за исключением тех, в состав которых входят мониторы.
- В получившейся виртуальной таблице некоторые строки могут повторяться. Причина повторений следующая. Название товара, собранного из нескольких компонентов, среди которых нет мониторов, встречается в нескольких строках таблицы COMPJUSED. И каждой такой строке соответствует отдельная строка в получившейся виртуальной таблице.
В этом примере количество строк не является проблемой, потому что получившаяся виртуальная таблица является короткой. Однако в реальной жизни такая таблица может состоять из сотен и тысяч строк. Чтобы не было путаницы, повторяющиеся строки необходимо убирать. Это сделать достаточно легко, если в запрос вставить ключевое слово DISTINCT (различный). Тогда в виртуальную таблицу будут добавляться только те строки, которые отличаются от уже имеющихся:
SELECT DISTINCT Model FROM COMP_USED WHERE Model NOT IN (SELECT Model FROM COMP_USED WHERE CompID IN (SELECT CompID FROM COMPONENT WHERE CompType = 'Monitor'));
Как и ожидалось, результат получился следующий:
Model -------- РХ3040 РВ3050
Вложенные запросы, возвращающие одно значение
Часто перед подзапросом полезно ставить один из шести операторов сравнения (=, <>, <, <=, >, >=). Это можно делать тогда, когда у выражения, стоящего перед оператором, вычисляется единственное значение, а подзапрос, стоящий после оператора, также выдает одно значение. Исключением является оператор сравнения, сразу после которого находится квантор (ANY, SOME или ALL).
Чтобы проиллюстрировать случай, когда вложенный подзапрос возвращает единственное значение, вернемся к базе данных корпорации Zetec. В ней имеется таблица CUSTOMER (покупатель), содержащая информацию о компаниях, которые покупают товары Zetec. Кроме того, в ней имеется еще другая таблица, CONTACT (представитель для контакта), с личными данными о контактных представителях каждой компании-клиента. Структура этих таблиц приведена в табл. 11.4 и 11.5.
Таблица 11.4. Таблица CUSTOMER.
Столбец | Тип | Ограничения |
---|---|---|
CustiD (идентификатор покупателя) | INTEGER | PRIMARY KEY |
Company (компания) | CHAR (40) | |
СustAddress (адрес покупателя) | CHAR (30) | |
Custcity (из какого города покупатель) | CHAR (20) | |
Custstate (из какого штата) | CHAR (2) | |
Сustzip (почтовый код покупателя) | CHAR (10) | |
CustPhone (телефон покупателя) | CHAR (12) | |
ModLevel | INTEGER |
Таблица 11.5. Таблица CONTACT.
Столбец | Тип | Ограничения |
---|---|---|
CustID | INTEGER | FOREIGN KEY |
ContFName (имя представителя) | CHAR (10) | |
СontLName (фамилия представителя) | CHAR (16) | |
ContPhone (телефон представителя) | CHAR (12) | |
Continfo (информация о представителе) | CHAR (50) |