Короткий ответ
Нужно последовательно сравнить определения метрики, окна времени, таймзоны, фильтры и момент обновления данных в дашборде и в прямом запросе — расхождение почти всегда объясняется различием в одном из этих параметров, а не ошибкой в данных.
Как это работает подробнее
дашборды часто используют предрасчитанные агрегаты (кэш, материализованные представления), которые обновляются с задержкой, используют своё определение "активности" (например, исключают тестовые аккаунты) и свою таймзону; прямой запрос к сырым данным может не учитывать эти нюансы.
Пример кода
retention_check.sql
-- Проверка таймзоны: сравнение событий в UTC и в локальной таймзоне пользователя
SELECT
COUNT(DISTINCT user_id) FILTER (WHERE event_time::date = DATE '2024-03-15') AS utc_based,
COUNT(DISTINCT user_id) FILTER (
WHERE (event_time AT TIME ZONE 'UTC' AT TIME ZONE 'Europe/Moscow')::date = DATE '2024-03-15'
) AS msk_based
FROM events;Что использовать на практике
- Практика. стоит проверить по порядку: 1) дата последнего обновления дашборда (lag); 2) фильтры, применённые в дашборде по умолчанию (исключение ботов, внутренних аккаунтов, конкретных стран); 3) таймзона агрегации; 4) точное определение retention (classic vs rolling, окно в днях); 5) дедупликация событий.
Подводные камни
- Частые ошибки. сразу предполагают ошибку в SQL-запросе или баг в дашборде, не проверив методологические различия; не документируют найденную причину расхождения, из-за чего та же путаница повторяется у других аналитиков позже.