Подзапросы и CTE
SQL подзапросы и CTE (WITH)¶
Когда одного SELECT не хватает, используем подзапросы и CTE — это делает запросы понятнее.
Подзапросы¶
1) Подзапрос в WHERE: IN¶
Покажем пользователей, у которых есть заказы:
2) EXISTS: существует ли хотя бы одна строка?¶
EXISTS часто эффективен, потому что может остановиться на первой найденной строке.
3) Коррелированный подзапрос¶
Подзапрос, который ссылается на внешнюю строку:
SQL
SELECT
u.id,
u.name,
(
SELECT COUNT(*)
FROM orders o
WHERE o.user_id = u.id
) AS orders_count
FROM users u
ORDER BY u.id;
CTE (WITH): запрос "по шагам"¶
CTE (Common Table Expression) — это способ писать запрос как цепочку понятных шагов.
SQL
WITH order_totals AS (
SELECT
o.id AS order_id,
o.user_id,
SUM(oi.qty * oi.price) AS total
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
GROUP BY o.id, o.user_id
)
SELECT *
FROM order_totals
WHERE total >= 100
ORDER BY total DESC;
Сначала считаем, потом фильтруем и сортируем.
Рекурсивный CTE (продвинутый уровень)¶
Нужен для деревьев: категории, оргструктура, комментарии.
SQL
WITH RECURSIVE tree AS (
-- 1) базовый уровень (корень)
SELECT id, parent_id, name, 0 AS depth
FROM categories
WHERE parent_id IS NULL
UNION ALL
-- 2) рекурсивный шаг (дети)
SELECT c.id, c.parent_id, c.name, t.depth + 1
FROM categories c
JOIN tree t ON t.id = c.parent_id
)
SELECT *
FROM tree
ORDER BY depth, name;
Если вы новичок — просто запомните, что инструмент есть; он отлично работает для иерархий.