|
Программирование >> Sql: полное руководство
Теперь перефразируем этот запрос таким образом: Вывести список товаров, для которых в таблице orders существует по крайней мере один заказ, удовлетворяющий условиям: а) является заказом на данный товар; б) имеет стоимость не менее чем $25000 . Инструкция select, используемая для получения требуемого списка товаров, приведена ниже: select description from products where exists (select order num from orders where product = product id and mfr = mfr id and amount >= 25000.00) descA:ption 500-lb Brace Left Hinge Right Hinge Widget Remover Главный запрос последовательно перебирает все строки таблицы products, и длч каждого товара выполняется подчиненный запрос. Результатом подчиненного запроса является столбец данных, содержащий номера всех заказов текущего товара на сумму не меньше чем $25000. Если такие заказы есть (т.е. столбец не пустой), то проверка exists возвращает true. Если подчиненный запрос не дает ни одной строки заказов, проверка exists возвращает значение false. Эта проверка не может возвращать null. Можно изменить логику проверки exists и использовать форму not exists. Тогда в случае, если подчиненный запрос не создает ни одной строки результата, проверка возвращает true, в противном случае ~ false. Обратите внимание на то, что предикат exists в действительности вовсе не использует результаты подчиненного запроса. Проверяется только наличие результатов. По этой причине в SQL смягчается правило, согласно которому подчиненный запрос должен возвращать один столбец данных , и в подчиненном запросе проверки exists допускается использование формы select *. Поэтому предьщущий запрос можно переписатт)/следующим образом: Вывести список товаров, на которые получен заказ стоимостью $25000 или больше. select description from products where exists (select * from orders where product = product id and mfr = mfr id and amount >= 25000.00) Ha практике при использовании подчиненного запроса в проверке exists всегда Применяется форма select *. Ниже показаны дополнительные примеры запросов, в которых возможна поверка exists: Вывести список клиентов, закрепленных за Сью Смит (Sue Smith), которые не сделали заказы на сумму свыше $3000. SELECT COMPANY FROM CUSTOMERS WHERE CUST REP = (SELECT EMPL NOM FROM SALESREPS WHERE NAME = Sue Smith) AND NOT EXISTS (SELECT * FROM ORDERS WHERE CUST = CUST NUM AND AMOONT > 3000.00) COMPANY Carter & Sons Fred Lewis Corp. Вывести список офисов, где имеется служащий, чей план превышает 55 процентов от плана офиса. SELECT CITY FROM OFFICES WHERE EXISTS (SELECT * FROM SALESREPS WHERE REP OFFICE = OFFICE AND QUOTA > (.55 * TARGET)) CITY Denver Atlanta Отметим, что во всех приведенных примерах подчиненный запрос содержит внешнюю ссылку на столбец таблицы из главного запроса. На практике в подчиненном запросе проверки exists всегда имеется внешняя ссылка, связывающая подчиненный запрос со строкой, проверяемой в настоящий момент главным запросом. Многократное сравнение (предикаты ANY и ALL) * в проверке in выясняется, не равно ли некоторое значение одному из значений, содержащихся в столбце результатов подчиненного запроса. В SQL имеются также две разновидности многократного сравнения - any и all, расширяющие предьщу-шую проверку до уровня других операторов сравнения, таких как больше (>) тли меньше (<). Как показано на рис. 9.6, в обеих проверках некоторое значение сравнивается со столбцом данных, отобранных подчиненным запросом. - проввряемое выраженив- <= > -ANY--ALL. - подчинвнный запрос Рис. 9.6. Синтаксическая диаграмма многократного сравнения (предикаты ANi и ALL) npeffftKOT ANY * В проверке ANY, для того чтобы сравнить проверяемое значение со столбцом данных, отобранных подчиненным запросом, используется один из шести операторов сравнения (=, о, <, <=, >, >=). Проверяемое значение поочередно сравнивается с каждым элементом, содержащимся в столбце. Если любое из этих сравнений дает результат true, то проверка any возвращает значение true. Вот пример запроса с предикатом any: Вывести список служащих, принявших заказ на сумму большую, чем десять процентов от их плана. SELECT NAME FROM SALESREPS WHERE (.1 * QOOTA < ANY NAME (SELECT AMOUNT FROM ORDERS WHERE REP = EMPL NUM) Bob Smith Paul Cruz Sam Clark Larry Fitch Главный запрос по очереди проверяет все строки таблицы SALESREPS. Подчиненный запрос находит все заказы, принятые текущим служащим, и возвращает столбец, содержащий стоимости этих заказов. Предложение where главного запроса вьписляет десять гфоцентов от плана текущего служащего и использует это число в качестве гфоверяемого значения, сравнивая его со стоимостью каждого заказа, отобранного подчиненным запросом. Если есть хотя бы один заказ, стоимость которого превышает вычисленное проверяемое значение, то проверка < any возвращает значение true, а имя служащего заносится в таблицу результатов запроса. Если таких заказов нет, имя служащего в таблицу результатов запроса не попадает. В соответствии со стандартом ANSI/ISO вместо предиката ANY можно использовать предикат SOME. Обычно можно употреблять любой из них, но некоторые СУБД не поддерживают предикат SOME.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |