Материал: Graber_Martin_-_SQL_dlya_prostykh_smertnykh_-_2014

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Глава 11. Связанные подзапросы

Связанные подзапросы в НАVING

В предложении HAVING могут использоваться и связанные подзапросы. В этом случае необходимо ограничить внешние ссылки теми элементами, которые могут не­ посредственно применяться в самом предложении HAVING. Как стало известно из главы 6, предложение HAVING может использовать только функции агрегирования из предложения SELECT или поля из предложения GROUP ВУ. Это и есть единственные внешние ссылки, которые можно делать, потому что предикат предложения HAVING оценивается для каждой группы из внешнего запроса, а не для каждой строки. Следо­ вательно, подзапрос будет выполняться один раз для каждой группы выходных дан­ ных внешнего запроса, а не для каждой отдельной строки.

Предположим, необходимо суммировать значения поля amounts (amt) таблицы

Orders, сгруппировав их по датам и исключив те дни, когда сумма не превышает мак­

симальное значение, по крайней мере на 2000.00:

SELECT odate, SUM (amt)

FROM Orders а

GROUP ВУ odate

HAVING SUM (amt) >

(SELECT 2000.00 + МАХ (amt) FROM Orders Ь

WHERE a.odate = b.odate);

Подзаnрос вычисляет максимальное (МАХ) значение для всех строк с одной и той же датой, совпадающей с датой, для которой сформирована очередная группа основ­ ного запроса. Это должно быть сделано, как показано в данном примере, с помощью предложения WHERE. В самом подзапросе не должно быть предложений GROUP ВУ

и HAVING.

Связанные подзапросы и соединения

Связанные подзапросы имеют близкое сходство с соединениями, так как оба вари­ анта включают сравнение каждой строки таблицы с каждой строкой другой (или алиа­ сом той же самой) таблицы. Сходство заключается и в том, что многие операции,

которые можно выполнить с помощью одного варианта, выполнимы и с помощью

другого.

Различие в их применении заключается в ранее упомянутой необходимости ис­ пользовать иногда DISТINCT в команде соединения Uoin), тогда как этого не требует­

ся в подзапросах. Есть также ряд вещей, которые можно сделать только с помощью

одного из этих вариантов. Подзапросы, например, могут использовать агрегатные функции в предикате, позволяя выполнить операции, подобные рассмотренной в пре­

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

114

Итоги

значение для данного покупателя. С другой стороны, соединения позволяют получать строки из двух таблиц, участвующих в сравнении, тогда как выходные данные подза­ просов могут использоваться только в предикатах внешних запросов. Согласно про­ стому правилу, лучше, вероятно, использовать ту форму запроса, которая кажется интуитивно более понятной, однако предпочтительно знать оба варианта на случай,

если один из них окажется неприемлемым.

Итоги

В главе было рассмотрено одно из сложных понятий SQL - связанные подзапро­ сы. Мы выяснили, как они соотносятся с операцией соединения, как их можно исполь­ зовать с функциями агрегирования и с предложением HAVING. Вы ознакомились со

всеми типами подзапросов.

Следующий шаг - введение некоторых специальных операторов, использующих, как и оператор IN, подзапросы в качестве аргументов, но в отличие от IN применяемых толь­ ко с подзапросами. Первый из них, EXISTS, рассмотрен в главе 12.

115

Работаем на SQL

1.Запишите команду SELECT, использующую связанные подзапросы и выбираю­ щую имена и номера всех покупателей, рейтинг которых совпадает с максималь­

ным значением рейтинга для их города.

2.Запишите два запроса, которые выбирают (по имени и номеру) всех продавцов,

проживающих в городах, где у них нет покупателей. Один запрос должен ис­ пользовать операцию соединения (join), а второй - связанные подзапросы. Ка­ кое из решений является более элегантным?

(Подсказка: один из возможных вариантов решения этой задачи - найти всех покупателей, не обслуживаемых данным продавцом, и посмотреть, не находятся ли они в одном городе.)

(Ответы см. в 1tриложении А.)

116

Использование

оператора EXISTS

Глава 12. Использование оператора EXJSTS

В этой главе речь пойдет о специальных операторах, всегда использующих под­

запросы в качестве аргументов, в частности, об операторе EXISTS.

Этот оператор применяется для образования предиката, фиксирующего, будет ли

подзапрос генерировать выходные данные. Вы научитесь использовать оператор

EXISTS в обычных и связанных подзапросах. Будут рассмотрены специальные случаи его употребления для агрегатов, NULL-значений и булевых значений. Вы сможете усовершенствовать навыки работы с подзапросами, рассматривая более сложные спо­ собы их применения.

Как работает оператор EXISTS?

EXISTS - оператор, генерирующий значение "истина" или "ложь", другими сло­ вами, булево выражение. Это значит, что его можно применять отдельно в предикате или комбинировать с другими булевыми выражениями с помощью операторов AND, OR и NOT. Используя подзапрос в качестве аргумента, этот оператор оценивает его

как истинный, если он генерирует выходные данные, а в противном случае как лож­

ный. В отличие от прочих операторов и предикатов, он не может принимать значение unknown. Например, нужно извлечь данные из таблицы Customers в том случае, если один (или более) покупатель из нее находится в San Jose (выходные данные для запро­

са представлены на рис. 12. l ):

SELECT cnum, cname, city

FROM Customers

WHERE EXISTS

 

Giovanni

 

 

 

Liu

 

 

 

Grass

 

 

 

Clemens

London

 

 

C1sneros

San Jose

 

 

Pereira

Rome

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 12.1. Использование оператора EXISTS

118

Источник: https://studfile.net/preview/16418473/