SQL позволяет использовать одни запросы внутри других запросов, то есть вкладывать запросы друг в друга. Предположим, известно название издательства (VHS), но неизвестно значение поля PUB_ID для него. Чтобы извлечь данные обо всех изданиях, можно сформулировать следующий запрос:
SELECT title FROM titles WHERE pub_id = (SELECT pub_id FROM publishers WHERE publisher = ‘VHS’);
Как работает запрос SQL со связанным подзапросом?
• Выбирается строка из таблицы, имя которой указано во внешнем запросе.
• Выполняется подзапрос и полученное значение применяется для анализа этой строки в условии предложения WHERE внешнего запроса.
• По результату оценки этого условия принимается решение о включении или не включении строки в состав выходных данных.
• Процедура повторяется для следующей строки таблицы внешнего запроса.
Следует обратить внимание, что приведенный выше запрос корректен только в том случае, если в результате выполнения указанного в скобках подзапроса возвращается единственное значение. Еслив результате выполнения подзапроса возвращается несколько значений, то этот подзапрос будет ошибочным. В данном примере это произойдет, если в таблице publishers будет несколько записей со значениями поля publisher = ‘VHS’.
В некоторых случаях для гарантии получения единственного значения в результате выполнения подзапроса используется DISTINCT. Одним из видов функций, которые автоматически всегдавыдают в результате единственное значение для любого количества строк, являются агрегирующие функции.
Оператор INтакже применяется в подзапросах. Он задает список значений, с которыми сравниваются другие значения для определения истинности, задаваемого этим оператором предиката.
Данные обо всех издательствах (таблица publishers), издавших литературу в 2000 году можно выбрать с помощью следующего запроса:
SELECT publisher FROM publishers WHERE pub_id IN (SELECT pub_id FROM titles WHERE yearpub = ‘2000’);
Подзапросы можно применять внутри предложения HAVING.
Пусть требуется определить издательства, количество изданий которых больше чем у издательства ‘VHS’:
SELECT publisher, COUNT(b.pub_id) FROM publishers AS a INNER JION titles AS b ON a.pub_id = b.pub_id GROUP BY publisher HAVING COUNT(pub_id)>(SELECT COUNT(b.pub_id) FROM publishers AS a INNER JION titles AS b ON a.pub_id = b.pub_id WHERE publisher = ‘VHS’);