Короткий ответ
Нужно сравнить определения метрики и границы фильтров в обоих местах (период, статусы заказов, включены ли возвраты/отмены, часовой пояс), а затем по шагам сузить расхождение через разбивку по дням/статусам/источникам, а не сразу искать ошибку в коде дашборда.
Как это работает подробнее
Как это работает: расхождение в 8% редко означает «дашборд врёт» — чаще это разные правила агрегации: например, дашборд может фильтровать status != 'cancelled', а отчёт источника считает все заказы; или дашборд использует order_date, а отчёт — payment_date; или часовой пояс границы месяца отличается (см. вопрос про UTC).
Пример кода
PostgreSQL: локализация расхождения
SELECT order_date::date AS day,
status,
source_system,
COUNT(*) AS orders_cnt,
SUM(amount) AS gross_amount,
SUM(amount) FILTER (WHERE status NOT IN ('cancelled', 'refunded')) AS net_amount
FROM orders
WHERE order_date >= TIMESTAMPTZ '2024-03-01 00:00:00+03'
AND order_date < TIMESTAMPTZ '2024-04-01 00:00:00+03'
GROUP BY order_date::date, status, source_system
ORDER BY day, status, source_system;Что использовать на практике
- На практике: эффективный порядок проверки: (1) сравнить фильтры WHERE/статусы в обоих запросах построчно; (2) разбить расхождение по дням — если оно сосредоточено у границ месяца, это сигнал про часовой пояс или про дату отсечки; (3) разбить по статусу заказа и источнику — если расхождение сосредоточено в одной категории, искать там; (4) сверить итоговую сумму на уровне нескольких конкретных order_id вручную.
- Проверка: Проверка: если разница в 8% сосредоточена в строках со статусом
cancelled, причина найдена — это вопрос определения метрики, а не технической ошибки.
Подводные камни
- Частые ошибки: сразу предполагают ошибку в формуле дашборда и переписывают его логику без проверки, что определения метрики в двух местах изначально разные; расследуют на агрегированном уровне, не спускаясь до конкретных строк, из-за чего причина остаётся гипотезой, а не подтверждённым фактом.