Теперь вы готовы к следующему шагу — работе с вложенными запросами в SQL. Сегодня мы разберём, что это такое, зачем они нужны, какие типы вложенных запросов бывают и почему они полезны в реальной жизни.
Вложенные запросы (или подзапросы) — это такие SQL-запросы, которые используются внутри других SQL-запросов. Такая себе матрёшка или капуста: есть внешний запрос, а внутри него спрятан другой, более маленький запрос. Подзапрос выполняется первым, а его результат используется внешним запросом (иногда его называют "главным").
Разберёмся на примере:
Пример 1: Как это работает
У нас есть таблица students со следующими данными:
| id | имя | возраст | группа_id |
|---|---|---|---|
| 1 | Алиса | 20 | 1 |
| 2 | Боб | 22 | 2 |
| 3 | Кларк | 21 | 1 |
| 4 | Дина | 23 | 3 |
| 5 | Эмилия | 22 | 2 |
А также таблица groups, в которой хранится информация о названиях групп:
| id | название |
|---|---|
| 1 | Математический класс |
| 2 | Физический класс |
| 3 | Литературный класс |
Если мы хотим узнать названия групп, в которых учатся студенты, то мы можем использовать вложенный запрос:
SELECT название
FROM groups
WHERE id IN (
SELECT группа_id
FROM students
WHERE возраст > 21
);
Что происходит здесь?
Вложенный запрос:
SELECT группа_id
FROM students
WHERE возраст > 21
Этот запрос выбирает группа_id всех студентов старше 21 года. Результат: список идентификаторов групп, например [2, 3].
Главный запрос:
SELECT название
FROM groups
WHERE id IN ([результаты подзапроса])
Этот запрос использует результаты подзапроса и возвращает названия групп с id равным 2 или 3.
Результат:
Физический класс
Литературный класс
Все еще ничего не понятно? Логично. Но не переживайте, сейчас мы все разберем.
Начнем с простой идеи — результат выполнения SELECT-запроса — это своего рода виртуальная таблица. Действительно, у нее есть колонки, у нее есть строки. Чем не таблица?
А если результат запроса — таблица, то ее можно использовать там же, где и реальные таблицы: в операторе JOIN, например, или в более сложных конструкциях.
У нее нет имени, и это проблема. Но у колонок-выражений тоже нет имен, и мы решаем эту проблему назначая им alias — псевдонимы. Тоже можно делать и с виртуальными таблицами.
Подробнее в следующих лекциях — не будем спойлерить :P
О пользе вложенных запросов
Они упрощают сложные задачи. Иногда одна таблица не содержит всей необходимой информации, которую вы хотите извлечь. Подзапросы позволяют разделить запрос на два этапа: сначала вы находите промежуточный результат, а затем используете его для получения финальных данных.
Работа с промежуточными результатами. Вложенные запросы полезны, когда вам нужно выполнить дополнительные вычисления перед тем, как обработать данные. Например, найти минимальное значение или подсчитать сумму.
Улучшение читаемости кода. Вложенные запросы делают код более структурированным, особенно если вы работаете с большими таблицами и сложной логикой.
Основные типы вложенных запросов
Вложенные запросы можно использовать в разных частях SQL-запроса. В зависимости от того, где вы их пишете, они делятся на несколько типов.
- Подзапросы в
SELECT. Подзапрос находится в списке столбцов и используется для вычисления значений. Это удобно, например, для добавления нового столбца в результаты.
Пример — добавим столбец с максимальным возрастом среди студентов:
SELECT имя, возраст,
(SELECT MAX(возраст) FROM students) AS максимальный_возраст
FROM students;
Результат:
| имя | возраст | максимальный_возраст |
|---|---|---|
| Алиса | 20 | 23 |
| Боб | 22 | 23 |
| Кларк | 21 | 23 |
| Дина | 23 | 23 |
| Эмилия | 22 | 23 |
- Подзапросы в
FROM. Подзапрос используется как временная таблица. Это полезно, если вам нужно сначала агрегировать или трансформировать данные.
Пример — подсчет среднего возраста студентов в каждой группе:
SELECT tmp.группа_id, tmp.средний_возраст
FROM (
SELECT группа_id, AVG(возраст) AS средний_возраст
FROM students
GROUP BY группа_id
) AS tmp -- Назначаем псевдоним tmp временной таблице
WHERE tmp.средний_возраст > 21;
Результат:
| группа_id | средний_возраст |
|---|---|
| 2 | 22.0 |
| 3 | 23.0 |
- Подзапросы в
WHEREиHAVING. Подзапросы могут быть условием, фильтрующим строки. Это часто используется для проверки - существования записей или для сравнения значений.
Пример — студенты, которые старше среднего возраста:
SELECT имя, возраст
FROM students
WHERE возраст > (
SELECT AVG(возраст)
FROM students
);
Результат:
| имя | возраст |
|---|---|
| Боб | 22 |
| Дина | 23 |
| Эмилия | 22 |
Преимущества использования вложенных запросов
Повышение гибкости: вложенные запросы позволяют работать с более сложными структурами данных.
Разделение задач на этапы: логику можно разделить на подзапросы, что делает код более читаемым.
Доступ к промежуточным данным: вы можете обрабатывать данные "на ходу", без необходимости создания временных таблиц в базе данных.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ