SQL-секция есть на большинстве технических собеседований для аналитиков и backend-разработчиков. Вот что реально спрашивают и как к этому готовиться.
Что проверяют на собеседовании
Компании не ждут знания всех нюансов PostgreSQL. Проверяют три вещи:
- Можете ли вы написать запрос без подсказок — базовый SELECT, JOIN, GROUP BY
- Понимаете ли вы что происходит — почему LEFT JOIN, а не INNER
- Можете ли вы решить нестандартную задачу — оконные функции, аналитика
Типичные вопросы
Уровень 1: Базовые (всегда спрашивают)
«Чем WHERE отличается от HAVING?» WHERE фильтрует строки до агрегации, HAVING — после. WHERE не может использовать агрегаты, HAVING — может.
«Какие типы JOIN существуют?» INNER, LEFT, RIGHT, FULL OUTER, CROSS. Самые частые — INNER и LEFT. Нужно понимать что происходит с несовпадающими строками в каждом случае.
«Что такое NULL и как с ним работать?»
NULL — отсутствие значения. = NULL не работает, нужно IS NULL. Агрегаты игнорируют NULL. COALESCE заменяет NULL на значение.
Уровень 2: Практические задачи
«Найдите топ-5 пользователей по сумме заказов»
SELECT user_id, SUM(amount) AS total
FROM orders
GROUP BY user_id
ORDER BY total DESC
LIMIT 5;
«Найдите пользователей, которые сделали заказ в январе, но не сделали в феврале»
SELECT DISTINCT user_id FROM orders
WHERE DATE_TRUNC('month', created_at) = '2024-01-01'
AND user_id NOT IN (
SELECT user_id FROM orders
WHERE DATE_TRUNC('month', created_at) = '2024-02-01'
);
«Для каждого отдела найдите сотрудника с максимальной зарплатой»
SELECT department, name, salary
FROM (
SELECT department, name, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rk
FROM employees
) ranked
WHERE rk = 1;
Уровень 3: Аналитические задачи (Яндекс, Авито, Ozon)
«Посчитайте 7-дневное скользящее среднее продаж»
SELECT
date,
revenue,
AVG(revenue) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW) AS moving_avg_7d
FROM daily_revenue;
«Посчитайте retention: какой процент пользователей вернулся на 7-й день»
WITH first_visit AS (
SELECT user_id, MIN(DATE(created_at)) AS first_day FROM events GROUP BY user_id
)
SELECT
COUNT(DISTINCT f.user_id) AS day0_users,
COUNT(DISTINCT CASE
WHEN DATE(e.created_at) = f.first_day + 7 THEN e.user_id
END) AS day7_users,
ROUND(100.0 * COUNT(DISTINCT CASE
WHEN DATE(e.created_at) = f.first_day + 7 THEN e.user_id
END) / COUNT(DISTINCT f.user_id), 1) AS retention_pct
FROM first_visit f
LEFT JOIN events e ON f.user_id = e.user_id;
Частые ошибки кандидатов
Не думают вслух. Интервьюер хочет видеть ход мыслей. Говорите что делаете и почему.
Сразу пишут сложное. Начните с простого запроса, потом усложняйте. Не пытайтесь сразу написать финальный вариант.
Не проверяют граничные случаи. «А что если у пользователя нет заказов? Что вернёт JOIN?» Интервьюеры ценят, когда кандидат сам об этом спрашивает.
Не знают своё решение. Если написали что-то, объясните почему. «Здесь LEFT JOIN потому что...» лучше молчания.
План подготовки за 2 недели
Дни 1–3: GROUP BY, HAVING, агрегатные функции. Решить 10–15 задач.
Дни 4–7: JOIN (INNER, LEFT, особенности NULL). Решить задачи с несколькими таблицами.
Дни 8–10: Подзапросы, CTE. NOT IN vs NOT EXISTS vs LEFT JOIN + IS NULL.
Дни 11–14: Оконные функции (ROW_NUMBER, RANK, LAG/LEAD, SUM OVER). Аналитические задачи.
По 40–60 минут в день — достаточно для прохождения SQL-секции в большинстве компаний.