Урок 4: Подзапросы — Когда Одного Запроса Недостаточно!
Привет снова, отважный исследователь данных! Если ты дошел до этого момента, то, наверное, думаешь: “Да это ж все проще пареной репы!” Но как только ты решаешь, что стал настоящим повелителем своих таблиц, PostgreSQL достает из рукава новый козырь: Подзапросы. Вот тут-то и начинается настоящая игра! Подзапросы — это как маленькие секретные миссии, спрятанные внутри основного запроса, которые выполняют всю грязную работу за кулисами.
Что такое Подзапрос?
Представь себе, что ты в ресторане. Ты заказал себе пиццу (основной запрос), но тихонько добавляешь официанту: “А еще, если есть возможность, добавьте побольше сыра.” Вот это и есть твой подзапрос! Подзапрос — это запрос, вложенный внутри другого запроса, который используется для уточнения или расширения результата основного запроса.
Подзапросы полезны в тех случаях, когда одного запроса просто недостаточно, например:
- Найти самых успешных рыцарей (по количеству выполненных заданий).
- Узнать, какие драконы сожгли больше трех деревень.
- Определить, какие рыцари нуждаются в, скажем, дополнительных тренировках.
Типы Подзапросов
Подзапросы бывают разных типов, в зависимости от того, как и где ты их используешь. Давай познакомимся с основными:
- Подзапросы, возвращающие одну строку: Они возвращают только одну строку. Идеально для быстрых проверок.
- Многозапросные Подзапросы: Возвращают несколько строк. Отлично подходят для сравнения списков!
- Скалярные Подзапросы: Возвращают одно значение. Круто подходят для скрытых сравнений.
- Коррелированные Подзапросы: Это настоящие шпионы — они знают, что происходит в основном запросе, и адаптируются на лету.
Давай посмотрим, как это работает!
Использование Подзапросов с SELECT
Начнем с простого примера. Допустим, у тебя есть таблица rycari
, и ты хочешь узнать, какой рыцарь выполнил больше всего заданий:
SELECT imya
FROM rycari
WHERE vypolnennye_missii = (SELECT MAX(vypolnennye_missii) FROM rycari);
Этот маленький подзапрос (SELECT MAX(vypolnennye_missii) FROM rycari)
выполняет свою работу, возвращает максимальное значение и передает его основному запросу, который затем говорит: “Покажи мне только тех рыцарей, у кого столько же выполненных миссий.”
Подзапросы в FROM
А теперь предположим, что ты хочешь сгруппировать рыцарей по королевствам и посмотреть среднее количество выполненных миссий. Обычный запрос может застрять, но подзапрос в FROM
справится играючи:
SELECT korolevstvo, AVG(vypolnennye_missii)
FROM (SELECT imya, korolevstvo, vypolnennye_missii FROM rycari) AS sub_rycari
GROUP BY korolevstvo;
Здесь наш подзапрос работает как временная таблица, ограничивая данные перед тем, как основной запрос начнет их обрабатывать.
Подзапросы в WHERE
Подзапросы часто используются в WHERE
, чтобы задать условия. Представь, что ты хочешь найти рыцарей, которые выполнили больше миссий, чем среднее значение по всем рыцарям:
SELECT imya
FROM rycari
WHERE vypolnennye_missii > (SELECT AVG(vypolnennye_missii) FROM rycari);
Подзапрос вычисляет среднее значение, а основной запрос говорит: “Покажи мне только тех рыцарей, которые выше среднего!” (Те, кто не протирает доспехи зря, короче говоря.)
Коррелированные Подзапросы: Шпионы SQL
Коррелированные подзапросы — это самые хитрые из всех. Они выполняются для каждой строки основного запроса и могут ссылаться на его столбцы. Допустим, ты хочешь узнать, какие рыцари выполнили больше миссий, чем средний показатель по их собственному королевству:
SELECT imya, korolevstvo
FROM rycari AS r1
WHERE vypolnennye_missii > (SELECT AVG(vypolnennye_missii)
FROM rycari AS r2
WHERE r2.korolevstvo = r1.korolevstvo);
Здесь подзапрос вычисляет среднее количество миссий для каждого королевства динамически. Это как шпион в основном запросе, который собирает информацию и передает ее на передовую.
Подзапросы в SELECT
Наконец, давай поговорим о подзапросах в SELECT
. Представь, что ты хочешь отчет, который показывает имя каждого рыцаря и то, как он соотносится с общей средней выполненных миссий:
SELECT imya,
vypolnennye_missii,
(SELECT AVG(vypolnennye_missii) FROM rycari) AS obshchaya_srednyaya
FROM rycari;
Теперь у тебя есть четкое сравнение, и все благодаря этому маленькому подзапросу, что прячется в основном запросе.
Объединим Все: Великий Парад Подзапросов!
Вот сценарий, который покажет все, что мы узнали:
Ты хочешь найти рыцарей, которые выполнили больше заданий, чем средний показатель, но только если они из королевств, где среднее количество миссий выше 3. Звучит сложно? Вот магия:
SELECT imya
FROM rycari
WHERE vypolnennye_missii > (SELECT AVG(vypolnennye_missii)
FROM rycari)
AND korolevstvo IN (SELECT korolevstvo
FROM rycari
GROUP BY korolevstvo
HAVING AVG(vypolnennye_missii) > 3);
Этот монстр-запрос использует подзапросы и в WHERE
, и в IN
условиях. Это как командовать целой армией маленьких запросов!
Что Мы Сегодня Узнали?
Сегодня мы погрузились в мир подзапросов:
- Подзапросы, возвращающие одну строку: Возвращают одну строку, используются для точных сравнений.
- Многозапросные Подзапросы: Возвращают несколько строк, идеально для списков.
- Скалярные Подзапросы: Возвращают одно значение, для скрытых сравнений.
- Коррелированные Подзапросы: Динамически подстраиваются под основной запрос.
Что Дальше?
В следующем уроке мы разберем CTE и Оконные Функции. Готовься поднять свои навыки SQL на новый уровень!
Добро пожаловать в мир подзапросов. Пусть ваши вложенные запросы всегда будут четкими, а результаты — точными!