SELECT onum, amt, odate
FROM Orders
WHERE snum IN ( SELECT snum
FROM Orders
WHERE cnum = 2001 );
Что случится, если есть ошибка и один из порядков был акредитован к различным продавцам? Версия, использующая IN, будет давать вам все порядки для обоих продавцов. Нет никакого очевидного способа наблюдения за ошибкой, и поэтому сгенерированные отчеты или решения, сделанные на основе этого запроса, не будут содержать ошибки. Вариант, использующий (=), просто потерпит неудачу.
Это, по крайней мере, позволило бы вам узнать, что имеется такая проблема. Вы должны затем выполнять поиск неисправности, выполнив этот подзапрос отдельно и наблюдая значения, которые он производит.
В принципе, если вы знаете, что подзапрос должен (по логике) вывести только одно значение, вы должны использовать =. IN является подходящим, если запрос может ограниченно производить одно или более значений, независимо от того ожидаете вы их или нет.
Предположим, мы хотим знать комиссионные всех продавцов обслуживающих заказчиков в Лондоне:
SELECT comm
FROM Salespeople
WHERE snum IN ( SELECT snum
FROM Customers
WHERE city = "London" );
Выводимыми для этого запроса, показанного в Рисунке 10.5, являются значения комиссионных продавца Peel (snum = 1001), который имеет обоих заказчиков в Лондоне. Это — только для данного случая. Нет никакой причины чтобы некоторые заказчики в Лондоне не могли быть назначеными к кому-то еще. Следовательно, IN — это наиболее логичная форма чтобы использовать ее в запросе.
=============== SQL Execution Log ==============
| SELECT comm |
| FROM Salespeople |
| WHERE snum IN |
| (SELECT snum |
| FROM Customers |
| WHERE city = 'London'); |
| =============================================== |
| comm |
| ------- |
| 0.12 |
=================================================
Рисунок 10.5: Использование IN с подзапросом для вывода одного значения
Между прочим, префикс таблицы для поля city необязателен в предыдущем примере, несмотря на возможную неоднозначность между полями city таблицы Заказчика и таблицы Продавцов.
SQL всегда ищет первое поле в таблице обозначенной в предложении FROM текущего подзапроса. Если поле с данным именем там не найдено, проверяются внешние запросы. В вышеупомянутом примере, "city" в предложении WHERE означает что имеется ссылка к Customer.city (поле city таблицы Заказчиков).
Так как таблица Заказчиков указана в предложении FROM текущего запроса, SQL предполагает что это — правильно. Это предположение может быть отменено полным именем таблицы или префиксом псевдонима, о которых мы поговорим позже когда будем говорить об соотнесенных подзапросах. Если возможен беспорядок, конечно же, лучше всего использовать префиксы.
ПОДЗАПРОСЫ ВЫБИРАЮТ ОДИНОЧНЫЕ СТОЛБЦЫ
Смысл всех подзапросов обсужденных в этой главе тот, что все они выбирают одиночный столбец. Это обязательно, поскольку выбранный вывод сравнивается с одиночным значением. Подтверждением этому то, что SELECT * не может использоваться в подзапросе. Имеется исключение из этого, когда подзапросы используются с оператором EXISTS, который мы будем представлять в Главе 12.
ИСПОЛЬЗОВАНИЕ ВЫРАЖЕНИЙ В ПОДЗАПРОСАХ
Вы можете использовать выражение основанное на столбце, а не просто сам столбец, в предложении SELECT подзапроса. Это может быть выполнено или с помощью реляционных операторов или с IN. Например, следующий запрос использует реляционный оператор = (вывод показывается в Рисунке 10.6):
Do'stlaringiz bilan baham: |