Скачиваний:
25
Добавлен:
01.04.2014
Размер:
761.34 Кб
Скачать

118 Понимание sql

______________________________________________________________________

ГЛ. 10

Хороший оптимизатор во всяком случае преобразует вариант обьединения

в подзапрос, но нет достаточно простого способа для вас чтобы выяснить

выполнено это или нет. Лучше сохранить ваши запросы в памяти чем по-

лагаться полностью на оптимизатор.

Конечно вы можете также использовать оператор IN, даже когда вы уве-

рены что подзапрос произведет одиночное значение. В любой ситуации где

вы можете использовать реляционный оператор сравнения (=), вы можете

использовать IN. В отличие от реляционных операторов, IN не может заста-

вить команду потерпеть неудачу если больше чем одно значение выбрано

подзапросом. Это может быть или преимуществом или недостатком.

Вы не увидите непосредственно вывода из подзапросов; если вы полагаете

что подзапрос собирается произвести только одно значение, а он производит

различные. Вы не сможете объяснить различия в выводе основного запроса.

Например, рассмотрим команду, которая похожа на предыдущую:

SELECT onum, amt, odate

FROM Orders

WHERE snum =

( SELECT snum

FROM Orders

WHERE cnum = 2001 );

Вы можете устранить потребность в DISTINCT используя IN вместо (=),

подобно этому:

SELECT onum, amt, odate

FROM Orders

WHERE snum IN

( SELECT snum

FROM Orders

WHERE cnum = 2001 );

Что случится если есть ошибка и один из порядков был акредитован к

различным продавцам? Версия использующая IN будет давать вам все

порядки для обоих продавцов. Нет никакого очевидного способа наблю-

дения за ошибкой, и поэтому сгенерированные отчеты или решения

сделанные на основе этого запроса не будут содержать ошибки. Вариант

использующий ( = ) , просто потерпит неудачу.

РАЗМЕЩЕНИЕ ЗАПРОСОВ ВНУТРИ ДРУГА ДРУГА 119

______________________________________________________________________

Это, по крайней мере, позволило вам узнать что имеется такая проблема.

Вы должны затем выполнять поиск неисправности, выполнив этот подза-

прос отдельно и наблюдая значения которые он производит.

В принципе, если вы знаете что подзапрос должен( по логике) вывести

только одно значение, вы должны использовать = .

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 с подзапросом для вывода одного значения

Соседние файлы в папке ПОНИМАНИЕ SQL