SQL для продакт-менеджера с нуля

Прокачай SQL для собеса
500+ задач по SQL: оконные функции, JOIN, CTE — с разбором каждой
Тренировать SQL в Telegram

Зачем SQL продакту

Продакт без SQL зависит от аналитика для каждого ad hoc-вопроса. С SQL — может за час сам проверить гипотезу, посмотреть статистику фичи, разобрать конкретный кейс.

На собесе SQL спрашивают почти везде — банки, маркетплейсы, IT-продукты. Уровень — base+ (JOIN, GROUP BY, оконки). Глубокую оптимизацию для PM не спросят, это территория аналитика.

Минимум для junior PM

  • SELECT, WHERE, ORDER BY, LIMIT
  • JOIN (LEFT, INNER) и базовое понимание разницы
  • GROUP BY и агрегаты (COUNT, SUM, AVG)
  • Оконные функции (ROW_NUMBER, SUM OVER) на узнавание
  • CTE (WITH) для читаемости

SELECT и WHERE

SELECT user_id, country, signup_date
FROM users
WHERE country = 'RU'
  AND signup_date >= '2026-01-01'
ORDER BY signup_date DESC
LIMIT 100;

WHERE фильтрует строки. Условия комбинируются через AND/OR. Сравнения дат — обычные операторы (>=, BETWEEN, <).

NULL обрабатывается отдельно — column IS NULL, не column = NULL.

JOIN

LEFT JOIN — все строки из левой таблицы + соответствующие из правой. Если справа нет — NULL.

INNER JOIN — только строки, где есть совпадение в обеих таблицах.

SELECT u.user_id, u.country, COUNT(o.order_id) AS orders_count
FROM users u
LEFT JOIN orders o ON o.user_id = u.user_id
GROUP BY u.user_id, u.country;

Если использовать INNER JOIN, юзеры без заказов выпадут из результата.

Главная ловушка: WHERE-условие на правой таблице после LEFT JOIN превращает его в INNER. Если хотите оставить NULL — фильтр в ON.

Прокачай SQL для собеса
500+ задач по SQL: оконные функции, JOIN, CTE — с разбором каждой
Тренировать SQL в Telegram

GROUP BY и агрегаты

GROUP BY группирует строки по колонке. Все колонки в SELECT либо группируются, либо агрегируются.

SELECT
  country,
  COUNT(*) AS users_count,
  AVG(age) AS avg_age,
  SUM(revenue) AS total_revenue
FROM users
GROUP BY country
HAVING COUNT(*) > 100;

HAVING фильтрует группы (после агрегации). WHERE — фильтрует строки до агрегации.

Полезные агрегаты:

  • COUNT(*) — все строки
  • COUNT(DISTINCT user_id) — уникальные значения
  • SUM, AVG, MIN, MAX
  • COUNT(*) FILTER (WHERE ...) — условный счёт (Postgres)

Оконные функции

Считают агрегат по группе, но возвращают результат для каждой строки (не сжимают в одну).

SELECT
  user_id,
  order_date,
  amount,
  ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY order_date) AS order_num,
  SUM(amount) OVER (PARTITION BY user_id ORDER BY order_date) AS cumulative_spent
FROM orders;

ROW_NUMBER() нумерует заказы внутри клиента. SUM() OVER даёт running total.

Для PM хватит знать: ROW_NUMBER, RANK, SUM OVER, LAG, LEAD.

Что спрашивают на собесе

Топ-задачи для PM:

  1. Топ-10 клиентов по выручке за месяц — простой GROUP BY + ORDER BY + LIMIT
  2. Какие юзеры сделали первый заказ в феврале — фильтр по MIN(order_date)
  3. Конверсия из регистрации в покупку — JOIN users + orders, COUNT с FILTER
  4. Retention 7-дневный — найти юзеров активных в день 0 и день 7
  5. Когорты — DATE_TRUNC регистраций, JOIN с активностью, GROUP BY когорт + день

На собесе оценят не идеальный SQL, а ход мысли: задаёт ли уточняющие вопросы, умеет ли декомпозировать, читает ли свой код.

Частые ошибки

WHERE на правой таблице после LEFT JOIN. Превращает в INNER JOIN. Используйте условие в ON.

SELECT все колонки + GROUP BY одной. Ошибка SQL — нужно либо группировать все, либо использовать агрегаты.

Считать дубликаты. COUNT(*) считает все строки, включая дубликаты. Используйте COUNT(DISTINCT user_id) для уникальных.

Integer division. 5/20*100 в Postgres = 0. 5::NUMERIC / 20 * 100 = 25.

Не использовать NULLIF. value/denominator → деление на ноль уронит запрос. Безопасно: value / NULLIF(denominator, 0).

FAQ

Какой диалект SQL учить?

Postgres — самый распространённый в РФ. Если идёте в маркетплейс или telecom — ClickHouse. Принципы 80% общие.

Сколько времени учить SQL до уровня PM?

При активной практике — 2-4 недели. Решать задачи каждый день по 30-60 минут.

Это официальная информация?

Нет. Статья основана на индустриальных практиках.