Назад 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Вперед
В выражении SELECT мы можем вводить подзапросы четырьмя способами:
Использовать в условии в выражении WHERE
Использовать в условии в выражении HAVING
Использовать в качестве таблицы для выборки в выражении FROM
Использовать в качестве спецификации столбца в выражении SELECT
Рассмотрим некоторые из этих случаев. Например, получим все товары, у которых цена выше средней:
Чтобы получить нужные товары, нам вначале надо выполнить подзапрос на получение средней цены товара: SELECT AVG(Price) FROM Products .
Или выберем всех покупателей из таблицы Customers, у которых нет заказов в таблице Orders:
Хотя в данном случае подзапросы прекрасно справляются со своей задачей, стоит отметить, что это не самый эффективный способ для извлечения данных из других таблиц, так как в рамках T-SQL для сведения данных из разных таблиц можно использовать оператор JOIN, который рассматривается в следующей теме.
Получение набора значений
При использовании в операторах сравнения подзапросы должны возвращать одно скалярное значение. Но иногда возникает необходимость получить набор значений. Чтобы при использовании в операторах сравнения подзапрос мог возвращать набор значений, перед ним необходимо использовать один из операторов: ALL , SOME или ANY .
При использовании ключевого слова ALL условие в операции сравнения должно быть верно для всех значений, которые возвращаются подзапросом. Например, найдем все товары, цена которых меньше чем у любого товара фирмы Apple:
Если бы мы в данном случае опустили бы ключевое слово ALL, то мы бы столкнулись с ошибкой.
Допустим, если подзапрос возвращает значения vl1, val2 и val3, то условие фильтрации фактически было бы аналогично объединению этих значений через оператор AND:
Как сделать вложенный запрос sql
Подзапросы являются одним из самых мощных инструментов в SQL, который можно использовать в любых видах запросов. В ближайших уроках мы познакомимся с основными типами подзапросов и рассмотрим примеры как их можно использовать.
Подзапрос — это запрос, использующийся в другом SQL запросе. Подзапрос всегда заключён в круглые скобки и обычно выполняется перед основным запросом.
Как и любой другой SQL запрос, подзапрос возвращает результирующий набор, который может быть одним из следующих:
- одна строка и один столбец;
- нескольких строк с одним столбцом;
- нескольких строк с несколькими столбцами.
В зависимости от типа результирующего набора подзапроса определяются операторы, которые могут использоваться в основном запросе.
Получим список всех бронирований самого дорогого на данный момент жилого помещения:
В данном случае запрос на получение самого дорого жилого помещения выполняется в качестве подзапроса, а затем результат результирующего набора применяется в основном запросе.
Подзапросы SQL
Часто невозможно решить поставленную задачу с помощью одного запроса. В этом случае используют подзапросы: внутренние, вложенные запросы.
Подзапрос представляет собой оператор SELECT , вложенный в тело другого оператора.
Кодирование подзапроса подчиняется тем же правилам, что и кодирование простого оператора SELECT . Внешний оператор использует результат выполнения внутреннего оператора для определения окончательного результата.
По количеству возвращаемых значений подзапросы разделяются на два типа:
- скалярные подзапросы, которые возвращают единственное значение;
- табличные подзапросы, которые возвращают множество значений.
По способу выполнения выделяют два типа подзапросов:
- простые подзапросы;
- сложные подзапросы.
Подзапрос называется простым, если он может рассматриваться независимо от внешнего запроса. СУБД выполняет такой подзапрос один раз и затем помещает его результат во внешний запрос.
Сложный подзапрос не может рассматриваться независимо от внешнего запроса. В этом случае выполнение оператора начинается с внешнего запроса, который отбирает каждую отдельную строку таблицы. Для каждой выбранной строки СУБД выполняет подзапрос один раз.
Простые скалярные подзапросы
Приведем примеры простых скалярных подзапросов.
Пример 1.
Определить наименования деталей, цена которых больше цены детали ‘болт’.
Данный подзапрос относится к скалярным, так как возвращает единственное значение — цену детали болт .
Подзапрос является простым, потому что он может рассматриваться независимо от внешнего запроса. СУБД сначала выполняет подзапрос, в результате чего получает цену детали болт — значение 10, а затем помещает это значение во внешний запрос и выполняет его.
Пример 2.
Определить номера деталей, цена которых меньше средней цены деталей.
Пример 3.
Определить номер поставщика, выполнившего поставку с минимальным объемом.
Пример 4.
Определить номера деталей, которых поставляется больше, чем деталей с номером 2.
Подзапросы можно использовать не только в предложении WHERE , но и в других предложениях оператора SELECT , например, в самом предложении SELECT .
Пример 5.
Вывести следующую информацию о деталях: наименование, цена, отклонение от средней цены.
В результате получим таблицу:
| dname | dprice | dif |
|---|---|---|
| болт | 10 | -10 |
| гайка | 20 | 0 |
| винт | 30 | 10 |
Простые табличные подзапросы
Если подзапрос возвращает множество значений, то его результат следует обрабатывать специальным образом. Для этого предназначены операции IN , ANY , SOME и ALL .
Такие операции могут использоваться с подзапросами, возвращающими таблицу, состоящую из одного столбца значений.
Операция IN
Операция IN осуществляет проверку на принадлежность значения множеству, которое получается после выполнения подзапроса.
Пример 6.
Определить наименования поставщиков, которые поставляют детали.
Такой подзапрос относится к табличным, так как возвращает множество значений. Подзапрос является простым, потому что он может рассматриваться независимо от внешнего запроса.
СУБД сначала выполняет подзапрос, в результате чего получает множество номеров поставщиков, которые поставляют детали. Затем СУБД проверяет номер каждого поставщика из таблицы P на принадлежность полученному множеству. При вхождении в множество наименование поставщика помещается в результирующую таблицу.
Пример 7.
Определить наименования поставщиков, которые не поставляют деталь с номером 2.
Пример 8.
Определить наименования поставщиков, которые поставляют только деталь с номером 1.
Операции ANY , SOME , ALL
Если подзапросу предшествует ключевое слово ANY , то условие сравнения считается выполненным, когда оно выполняется хотя бы для одного из значений, которые получаются после выполнения подзапроса.
Если подзапросу предшествует ключевое слово ALL , то условие сравнения считается выполненным, только если оно выполняется для всех значений, которые получаются после выполнения подзапроса.
Если в результате выполнения подзапроса получено пустое множество, то для операции ALL условие сравнения будет считаться выполненным, а для ключевого слова ANY — не выполненным.
Ключевое слово SOME является синонимом ANY и используется для повышения наглядности текстов запросов.
Пример 9.
Определить наименования поставщиков, которые поставляют детали.
Такой подзапрос относится к табличным, так как возвращает множество значений. Подзапрос является простым, потому что он может рассматриваться независимо от внешнего запроса.
СУБД сначала выполняет подзапрос, в результате чего получает множество номеров поставщиков, которые поставляют детали. Затем СУБД проверяет номер каждого поставщика из таблицы P на равенство хотя бы одному из номеров из полученного множества. При выполнении условия наименование поставщика помещается в результирующую таблицу.
Пример 10.
Определить наименование детали с максимальной ценой.
Последний пример можно решить следующим способом:
Сложные табличные подзапросы
Операция EXISTS
Результат выполнения таких операций представляет собой значения TRUE или FALSE .
Для операции EXISTS результат равен TRUE , если в возвращаемой подзапросом таблице присутствует хотя бы одна строка. Если в результирующей таблице подзапроса пуста, то операция EXISTS возвращает значение FALSE . Для операции NOT EXISTS используются обратные правила обработки.
Поскольку обе операции проверяют лишь наличие строк в результирующей таблице подзапроса, то эта таблица может содержать произвольное количество столбцов.
Пример 11.
Определить наименования поставщиков, которые поставляют детали.
Такой подзапрос относится к табличным, так как возвращает множество значений. Подзапрос является сложным, потому что он не может выполняться независимо от внешнего запроса.
В этом случае выполнение оператора начинается с внешнего запроса, который поочередно отбирает каждую отдельную строку таблицы P. Для каждой выбранной строки СУБД выполняет подзапрос один раз. В результирующую таблицу помещаются только те наименования поставщиков, для которых подзапрос возвращает хотя бы одну строку.
Первой выбирается строка с информацией о поставщике Иванов. В подзапрос вместо P.pnum подставляется значение 1 (номер поставщика Иванова), после чего подзапрос выполняется.
Подзапрос возвращает три первых строки из таблицы PD, соответствующие поставкам Иванова, поэтому результат операции EXISTS равен TRUE , и наименование Иванов помещается в результирующую таблицу.
Аналогично результат получается для поставщиков Петров и Сидоров. При выборе строки с информацией о поставщике Кузнецов, подзапрос возвращает пустое множество, поэтому результат операции EXISTS равен FALSE , и наименование Кузнецов не помещается в результирующую таблицу.
Создание самосоединений
При самосоединении используются псевдонимы таблиц, которые позволяют различать соединяемые копии таблиц. Псевдонимы вводятся в предложении FROM и используются как обычные имена таблиц.
Пример 12.
Определить наименования поставщиков, которые поставляют и деталь с номером 1, и деталь с номером 2.
Один из вариантов решения задачи можно записать с помощью подзапроса следующим образом.
Тот же самый результат можно получить используя соединение таблицы PD с ее копией, назовем ее PD1, следующим образом:
Пример 13.
Определить наименования поставщиков, которые поставляют и деталь с номером 1, и деталь с номером 2, и деталь с номером 3.
Резюмирую
Из этой статьи вы узнали что такое подзапрос в SQL. Теперь вы легко отличите скалярный запрос от табличного, и простой запрос от сложного.
Также мы рассмотрели на примерах такие операции, как IN , ANY , SOME и ALL .
Подзапросы в SQL
В SQL мы можем поместить один запрос внутри другого запроса (сделав подзапрос). В подзапросе результат внешнего запроса зависит от результатов внутреннего запроса. Вот почему подзапросы также называют вложенными запросами. Например:
Здесь сначала выполняется подзапрос (внутренний запрос) — мы выбираем наименьшее значение age из таблицы Customers. Затем выполняется внешний запрос — мы выбираем строки, в которых age равен результату подзапроса (наименьшему значению age).

Рассмотрим другой пример. Предположим, нам нужны сведения о клиентах, разместивших заказ. Вот как мы можем это сделать с помощью подзапроса: