Латеральные соединения (LATERAL JOIN)
Обращайтесь к предыдущему элементу FROM из подзапроса с помощью LATERAL — это эквивалент вызова функции для каждой строки в SQL
«Латеральные соединения (LATERAL JOIN)» — бесплатный урок SQL Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения SQL Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс SQL Academy содержит 4 уроков всего.
Что такое LATERAL?
LATERAL позволяет подзапросу в предложении FROM обращаться к столбцам элементов, расположенных раньше в списке FROM. Без LATERAL элементы FROM не могут видеть друг друга.
Ментальная модель
LATERAL означает: «для каждой строки левой стороны выполнить этот запрос». Это похоже на коррелированный подзапрос, но находится в предложении FROM и возвращает несколько строк и столбцов.
Три лучших заказа для каждого пользователя
Классический сценарий использования LATERAL:
SELECT u.id, u.email, o.id AS order_id, o.total
FROM users u
JOIN LATERAL (
SELECT id, total FROM orders
WHERE user_id = u.id
ORDER BY total DESC
LIMIT 3
) AS o ON true;Почему не подзапрос в SELECT?
Скалярный подзапрос в SELECT возвращает одно значение. LATERAL возвращает несколько строк и несколько столбцов для каждой внешней строки.
LATERAL с функциями
Функции, возвращающие набор строк, по умолчанию ведут себя подобно LATERAL:
SELECT t.id, unnest_tag
FROM posts t
CROSS JOIN LATERAL unnest(t.tags) AS unnest_tag;
-- Equivalent (set-returning functions are implicit LATERAL):
SELECT t.id, unnest_tag
FROM posts t, unnest(t.tags) AS unnest_tag;LATERAL и оконные функции
Для задачи «топ-N в каждой группе» подходят и LATERAL, и ROW_NUMBER. ROW_NUMBER часто эффективнее, потому что обходит таблицу один раз, а LATERAL повторно выполняет запрос для каждой внешней строки.
-- ROW_NUMBER alternative:
WITH ranked AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY total DESC) AS rn
FROM orders
)
SELECT u.email, r.id, r.total
FROM users u
JOIN ranked r ON r.user_id = u.id
WHERE r.rn <= 3;LATERAL с агрегатными функциями
Предварительно вычисленные значения для каждой строки:
SELECT u.email, stats.last_order_at, stats.total_orders
FROM users u
LEFT JOIN LATERAL (
SELECT MAX(created_at) AS last_order_at,
COUNT(*) AS total_orders
FROM orders WHERE user_id = u.id
) AS stats ON true;ON true
Для LATERAL в соединении требуется предложение ON, но условие соединения находится внутри подзапроса, поэтому внешнее ON имеет значение true.
CROSS JOIN LATERAL и LEFT JOIN LATERAL
- CROSS JOIN LATERAL — внешняя строка отбрасывается, если внутренний запрос не возвращает строк
- LEFT JOIN LATERAL ... ON true — внешняя строка сохраняется, а столбцы заполняются NULL
LATERAL для запросов по расстоянию
Ближайший магазин для каждого пользователя:
SELECT u.id, s.name, s.distance
FROM users u
CROSS JOIN LATERAL (
SELECT name, location <-> u.location AS distance
FROM stores
ORDER BY location <-> u.location
LIMIT 1
) AS s;LATERAL соответствует стандарту SQL
Стандартизирован в SQL:1999. PostgreSQL реализует его с помощью LATERAL; SQL Server использует CROSS APPLY и OUTER APPLY.
Производительность
LATERAL выполняется отдельно для каждой внешней строки. При наличии подходящего индекса во внутренней таблице каждая итерация выполняется быстро. Без такого индекса работа может замедлиться при больших объёмах данных.
Итоги
LATERAL = «подзапрос в FROM, который видит внешнюю строку».
- Топ-N в каждой группе
- Предварительные вычисления для каждой строки
- Функции, возвращающие набор строк
- Сочетание с LEFT JOIN ... ON true для внешних соединений
Быстрая проверка
Что позволяет делать LATERAL, чего не позволяет обычный подзапрос в FROM?
Часто задаваемые вопросы
Урок «Латеральные соединения (LATERAL JOIN)» бесплатный?
Да — полный текст урока «Латеральные соединения (LATERAL JOIN)» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс SQL Academy, подпишись на CoddyKit PRO. Курс SQL Academy содержит 4 уроков всего.
Чему я научусь в уроке «Латеральные соединения (LATERAL JOIN)»?
Обращайтесь к предыдущему элементу FROM из подзапроса с помощью LATERAL — это эквивалент вызова функции для каждой строки в SQL Ты практикуешь SQL Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать SQL Academy?
Предыдущий опыт не требуется. SQL Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Латеральные соединения (LATERAL JOIN)»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке SQL Academy?
Да. Каждый урок SQL Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Перекрёстные соединения и декартовы произведения
- Латеральные соединения (LATERAL JOIN)
- Антисоединения и полусоединения (NOT EXISTS)
- Оптимизация производительности соединений нескольких таблиц