Подчеркнём, что все формулировки с ANY и ALL могут быть в точности выполнены с EXISTS, в то время как обратное будет неверно. Хотя в этом случае также верно и то, что подзапросы EXISTS и NOT EXISTS могут проколоть при выполнении тех же самых подзапросов с COUNT(*) в предложении SELECT подзапроса. Если больше чем ноль строк в выводе будет подсчитано, это эквивалентно EXISTS; в противном случае это работает так же, как NOT EXISTS. Следующее является этому примером (вывод показан на Рисунке 13.12):
SELECT * FROM Customers outer WHERE NOT EXISTS (SELECT * FROM Customers inner WHERE outer.rating < = inner.rating AND inner.city = 'Rome'); =============== SQL Execution Log ============ | | | SELECT * | | FROM Customers outer | | WHERE NOT EXISTS | | (SELECT * | | FROM Customers inner | | WHERE outer.rating <= inner.rating | | AND inner.city = 'Rome'); | | ============================================= | | cnum cname city rating snum | | ----- -------- ---- ------ ------ | | 2004 Grass Berlin 300 1002 | | 2008 Cisneros San Jose 300 1007 | ============================================= Рисунок 13.12 Использование EXISTS с соотнесённым подзапросом
Это должно также быть выполнено как
SELECT * FROM Customers outer WHERE 1 > (SELECT COUNT (*) FROM Customers inner WHERE outer.rating < = inner.rating AND inner.city = 'Rome');
Вывод к этому запросу показан на Рисунке 13.13. Теперь вы начинаете понимать, сколько способов имеется в SQL. Если это всё кажется несколько сложным на данном этапе, нет причин волноваться. Вы обучаетесь, чтобы использовать ту технику, которая больше отвечает вашим требованиям и наиболее понятна для вас. Начиная с этого места, мы хотим показать вам большое количество возможностей, чтобы вы могли найти ваш собственный стиль.
=============== SQL Execution Log ============ | | | SELECT * | | FROM Customers outer | | WHERE 1 > | | (SELECT COUNT (*) | | FROM Customers inner | | WHERE outer.rating <= inner.rating | | AND inner.city = 'Rome'); | | ============================================= | | cnum cname city rating snum | | ----- -------- ---- ------ ------ | | 2004 Grass Berlin 300 1002 | | 2008 Cisneros San Jose 300 1007 | ============================================= Рисунок 13.13 Использование COUNT вместо EXISTS
РЕЗЮМЕ
Итак, вы узнали много нового в этой главе. Подзапросы - непростая тема, и мы потратили много времени, чтобы показать их варианты и неоднозначность. То, чему вы теперь научились, вещи достаточно глубокие. Вы знаете несколько технических решений одной проблемы, и поэтому можете выбрать то, которое больше подходит для ваших целей. Кроме того, вы поняли, как различные формулировки будут обрабатывать пустые значения (NULL) и ошибки.
Теперь, когда вы полностью изучили запросы - наиболее важный, и, вероятно, наиболее сложный аспект SQL - другой материал будет относительно прост для понимания.
У нас есть ещё одна глава о запросах, которая покажет вам, как объединить вывод любого количества запросов в единое тело с помощью формирования объединения нескольких запросов, используя оператор UNION.