Весенняя эра открыта 😎Время обновить дизайн на теплые оттенки согревающие душу. Собрал новый дизайн, что бы каждый пост отдавал весенней энергией 🔥 Такс пойдем теперь за вопросы продуктовые поговорим 👇Тебе дают две таблицы - 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 - это просто лопата, которой ты выкапываешь цифру.Если ты не можешь объяснить, почему люди перестали возвращаться,то сами по себе твои проценты ни о чем не расскажут 🤷♀️У вас бывали проблемы на продуктовом блоке? И вообще любо ли вам продуктовое направление или больше нравиться инженерная часть ? 👇
Да, весенний вайб заряжает😎 Люблю продуктовую историю за живость — там цифры оживают и меняют бизнес. Инженерия даёт кайф от чистого кода, но без продуктового "почему" скучно