|
В вышеупомянутом примере, "внутренний"(inner) и "внешний"(outer), это псевдонимы, подробно обсужденным в Главе 9 . Мы выбрали эти имена для большей ясности; они отсылают к значениям внутренних и внешних запросов, соответственно. Так как значение в поле cnum внешнего запроса меняется, внутренний запрос должен выполняться отдельно для каждой строки внешнего запроса. Строка внешнего запроса, для которого внутренний запрос каждый раз будет выполнен, называется - текущей строкой-кандидатом. Следовательно, процедура оценки выполяняемой соотнесенным подзапросом - это:
В вышеупомянутом примере, SQL осуществляет следующую процедуру:
Как вы можете видеть, вычисления которые SQL выполяняет с помощью этих простых инструкций - это полный комплекс. Конечно, вы могли бы решить ту же самую проблему Используя объединение, следующего вида ( вывод для этого запроса показывается в Рисунке 11.2 ): SELECT * FROM Customers first, Orders second WHERE first.cnum = second.cnum AND second.odate = 10/03/1990; Обратите внимание что Cisneros был выбран дважды, по одному разу для каждого порядка который он имел для данной даты. Мы могли бы устранить это Используя SELECT DISTINCT вместо просто SELECT. Но это необязательно в варианте подзапроса. Оператор IN, исполяьзуемый в варианте подзапроса, не делает никакого различи между значениями которые выбираются подзапросом один раз и значениями которые выбираются неоднократно. Следовательно DISTINCT необязателен .
Рисунок 11. 2 Использование объединения вместо соотнесенного подзапроса Предположим, что мы хотим видеть имена и номера всех продавцов, которые имеют более одного заказчика. Следующий запрос выполнит это для вас ( вывод показывается в Рисунке 11.3 ): SELECT snum, sname FROM Salespeople main WHERE 1 < ( SELECT COUNT (*) FROM Customers WHERE snum = main.snum ); Обратите внимание, что предложение FROM подзапроса в этом примере не использует псевдоним. При отсутствии имени таблицы или префикса псевдонима, SQL может для начала принять, что любое поле выводится из таблицы с именем, указанным в предложении FROM текущего запроса. Если поле с этим именем отсутствует( в нашем случае - snum ) в той таблице, SQL будет проверять внешние запросы. Именно поэтому, префикс имени таблицы обычно необходим в соотнесенных подзапросах - для отмены этого предполяожения. Псевдонимы также часто запрашиваются, чтобы давать вам возможность ссылаться к той же самой таблице во внутреннем и внешнем запросе без какой-либо неоднозначности.
Рисунок 11.3: Нахождение продавцов с многочисленными заказчиками
|
|||||||||||||||||||||||||||||||||||||||||||||