Бран · продюсер «Хроник Пограничья»
Ваш стажёр прислал, что 21 июня у нас был рекорд: 267 игроков за день. Если правда, повторяем тот ивент каждую неделю. Подтвердите?
В прошлом уроке мы решали вопрос с нуля и знали, где искать болячки. Чаще бывает иначе: цифра уже посчитана, её прислал коллега, и выглядит она правдоподобно. Сегодня разберём три таких «готовых ответа». В каждом сидит одна из классических ловушек данных.
Пять ловушек
Ловушки повторяются из базы в базу. Мы встречали каждую по отдельности, теперь соберём их в один список:
| Ловушка | Как выглядит | Где встречали |
|---|---|---|
| Дубли событий | одно действие оставляет несколько строк | повторные вебхуки, размножение строк при JOIN |
| Тестовые аккаунты | сотрудники студии покупают и играют | чистка строк |
| Боты | аккаунты играют по 24 часа | DAU и липкость |
| Часовые пояса | время в UTC сравнивают с местным | пояса |
| Ошибка выжившего | считают только тех, кто остался | когорты |
Ошибка выжившего самая коварная из пяти: запрос в ней написан без ошибок, ошибка в выборке.
Ответ первый: рекорд 21 июня
Стажёр написал так:
SELECT started_at::date AS day, count(*) AS dau
FROM sessions
WHERE started_at >= '2026-06-01' AND started_at < '2026-07-01'
GROUP BY day
ORDER BY dau DESC
LIMIT 1;
count(*) считает строки sessions, а у живого игрока в день бывает две-три сессии. Это ловушка дублей событий: одно «пришёл поиграть» оставляет несколько строк. Правильно считать разных игроков и убрать ботов и тестировщиков. Ботов узнаём по сессиям длиннее 20 часов, как в уроке про DAU:
WITH fake AS (
SELECT id FROM players WHERE email LIKE '%@studio.dev'
UNION
SELECT player_id FROM sessions WHERE ended_at - started_at > interval '20 hours'
)
SELECT started_at::date AS day,
count(*) AS sessions,
count(DISTINCT player_id) AS players,
count(DISTINCT player_id) FILTER (WHERE player_id NOT IN (SELECT id FROM fake)) AS dau_clean
FROM sessions
WHERE started_at >= '2026-06-01' AND started_at < '2026-07-01'
GROUP BY day
ORDER BY dau_clean DESC
LIMIT 3;
day | sessions | players | dau_clean
------------+----------+---------+-----------
2026-06-21 | 267 | 169 | 164
2026-06-20 | 264 | 169 | 163
2026-06-27 | 255 | 164 | 161
21 июня действительно самый людный день месяца, но людей было 164, а не 267. И это не рекорд ивента: на втором месте 20 июня, на третьем 27-е. Все три дня выходные.
урок из курса
Урок из курса «Аналитика данных с нуля». Курс покупается один раз и остаётся навсегда: 500 ₽.
Оплата пока не подключена: премиум и курсы открываются промокодом.