Весенняя эра открыта 😎Время обновить дизайн на теплые оттенки согревающие душу. Собрал новый дизайн, что бы каждый пост отдавал весенней энергией 🔥 Такс пойдем теперь за вопросы продуктовые поговорим 👇Тебе дают две таблицы - users и events. И 20 минут на задачу:«Посчитай батенька retention по когортам M0–M3»И вот на этом ловят ступор.А с чего вообще стартовать? 🤔Проще всего - не с SQL, а с картинки в голове. Представь спортзал.100 человек купили абонемент - это твоя когорта.Дальше обычно эту когорту принимают за 100%. Это и есть M0.
Но вот нюанс: это не закон природы, а просто негласное соглашение. На следующий день пришли 60 человек - Day 1 = 60%.Через неделю пришли 40 - Day 7 = 40%.Дальше логика не меняется.Просто вместо дней - месяцы.И вместо спортзала - продукт.
1️⃣ Junior-уровень - понять, сколько людей вообще пришло в каждую когортуSELECT DATE_TRUNC('month', registration_date) AS cohort_month, COUNT(DISTINCT user_id) AS new_usersFROM usersGROUP BY 1ORDER BY 1;Если уже здесь ошибка, все суши весла. Потому что DATE_TRUNC и DISTINCT - это база продуктового блока.Хотя бы для PostgreSQL и похожих диалектов.
2️⃣ Следующий уровень - понять, кто вернулсяWITH cohort_dec AS ( SELECT user_id, registration_date FROM users WHERE registration_date >= '2023-12-01' AND registration_date < '2024-01-01')SELECT COUNT(*) AS cohort_size, COUNT(DISTINCT CASE WHEN event_date = registration_date + 1 THEN user_id END) AS day1, COUNT(DISTINCT CASE WHEN event_date = registration_date + 7 THEN user_id END) AS day7FROM cohort_dec uLEFT JOIN events e ON u.user_id = e.user_id;
Тут под ноги бросаются грабли 🤔Такой код нормален, если даты у тебя хранятся как DATE, без времени.Но если это TIMESTAMP, простое равенство может ломать расчёт.Потому что у одного событие в
2023-12-08 00:01, у другого в
2023-12-08 19:42, и формально это уже не то же самое значение.Значит, нужно либо приводить к дате, либо считать через диапазоны.То есть логика всегда одна и та же:✅ зафиксировал когорту → посмотрел, кто вернулсяДля M1, M2, M3 всё почти то же самое, но есть принципиальный момент:👉 сравнивают не просто даты, а смещение по календарным месяцам относительно месяца регистрации ( да сложно звучит сейчас объясню )
То есть не +30 дней. Месяцы разной длины, поэтому такой расчёт съезжает.Для
месячного retention смотрят
смещение по календарным месяцам, а не просто прибавляют 30 дней.
❌ Где еще грабли поджидают1️⃣ Считают события вместо людейОдин пользователь сделал 5 событий.И внезапно retention у тебя больше 100%.Значит, ты считаешь не возврат людей, а активность.
2️⃣ Ставят INNER JOINИ в выборке остаются только те, кто вернулся.Все, кто отвалился, просто исчезают.Получается красивая цифра. И полностью фальшивая картина.
3️⃣ Не фиксируют базу расчётаРазмер когорты обычно принимают за 100%, и уже от него считают всё дальше.Если база у тебя гуляет, проценты превращаются в мусор.А дальше начинается главная беда...
тест на мышление и софты. Вот уж где самая тернистая тропа если мало опыта.Потому что на собесе тебя не спросят:«Как посчитать retention?»А спросят: «D30 упал. Почему?» Приехали...И вот тут SQL уже никого не впечатляет.
✅ Нормальный ход мысли такой:- разложить retention по когортам- посмотреть каналы привлечения- проверить activation- понять, не ломался ли онбординг- сравнить поведение до и после релизовМожно копать еще глубже, но для старта достаточно этих основ.
❌ Ответ который сразу поставит крест на вашем диалоге«Ну… retention снизился, потому что пользователи стали хуже возвращаться..»Спасибо товарищ Капитан. Но это не ответ аналитика, а догадка.Если простыми словами:
Retention - это не про SQL, это про поведение.SQL - это просто лопата, которой ты выкапываешь цифру.Если ты не можешь объяснить, почему люди перестали возвращаться,то сами по себе твои проценты ни о чем не расскажут 🤷♀️
У вас бывали проблемы на продуктовом блоке? И вообще любо ли вам продуктовое направление или больше нравиться инженерная часть ? 👇#собесы
@data_dzen 🙂