Как сделать дашборд: от вопроса бизнеса до публикации
Пошагово собираем дашборд на проверенных данных: решение и читатель, SQL для KPI, динамика, разрез, проверка чисел, доступы и дата обновления.
Содержание статьи
Коммерческий директор просит к пятнице дашборд продаж. Аналитик может сразу открыть BI и расставить графики, но через неделю обнаружится спор о том, что считать продажей и почему сумма в отчёте не совпала с оплатами. Начните с решения, которое директор примет по странице. Ниже мы пройдём весь путь на учебных бронированиях авиабилетов: запросы выполнены, числа можно повторить, а ограничения данных показаны рядом с графиками.
Коротко: как сделать дашборд
Сформулируйте решение и того, кто будет открывать страницу. Зафиксируйте период, единицу учёта, определения показателей и источник. Сверьте SQL-расчёт с контрольной таблицей. Разложите экран сверху вниз: итоговые числа, динамика, объясняющий разрез, детали. Добавьте не более тех фильтров, которые меняют решение. Укажите время последнего успешного обновления, права доступа и владельца. Покажите страницу заказчику на реальном вопросе, затем возвращайтесь к ней после месяца использования.
Это не инструкция по кнопкам конкретного инструмента: они меняются. Практический результат — спецификация страницы, запросы и таблицы приёмки, которые можно перенести в Excel или BI. Если требуется только одноразовый ответ «почему изменились продажи в августе», нужен разовый анализ, а не постоянно поддерживаемый дашборд.
Начните с решения, а не с перечня KPI
Для учебного кейса вопрос руководителя звучит так: «Сумма новых бронирований за прошлую полную неделю выросла или уменьшилась по сравнению с предыдущей, и в каких типах брони это заметно?» Возможное действие — проверить изменение тарифа или спроса только после того, как видно, какой сегмент внёс вклад. Страница не должна обещать причинный ответ: она показывает место для разбора.
Спросите, кто читает страницу, по понедельникам или каждый день, какую величину считает тревожным отклонением и что делает при тревоге. Для еженедельного решения достаточно обновления после закрытия недели. Обновлять цифру каждую минуту здесь бесполезно: руководитель не принимает решение так часто. Если ему нужна поштучная проверка крупных бронирований, таблица деталей должна быть доступна, но не занимать весь первый экран.
Вторая часть договора — право сказать «данных недостаточно». В учебной таблице есть стоимость брони, но нет возвратов, признания выручки и маркетингового канала. Поэтому карточка называется «сумма оформленных бронирований», а не «чистая выручка» и не «эффективность маркетинга». Такое точное название предотвращает дорогой спор после публикации.
Данные: одна строка — одно бронирование
В базе «Авиаперевозки» таблица bookings хранит одну строку на book_ref. У неё есть дата book_date и полная сумма total_amount в рублях. База — учебная производная от демо-базы Postgres Professional; даты перенесены в август 2026 года и записаны в московском времени без часового пояса. Мы берём полную неделю 3–9 августа и сравниваем с 27 июля — 2 августа. Срез данных заканчивается позже, 11 августа в 18:00, поэтому обе недели уже закрыты.
В одном бронировании может быть несколько билетов. Прямое соединение bookings с tickets превратит одно денежное событие в несколько строк и завысит сумму. Для разбивки по числу билетов сначала посчитайте билеты по book_ref, затем присоедините одну строку результата к одной брони. Если позднее захотите разложить стоимость по маршрутам, понадобится отдельное правило распределения денег: билет и рейс не дают его автоматически.
| Объект | Зерно | Нужное поле | Что проверить |
|---|---|---|---|
| bookings | Одна строка = одна бронь | book_ref, book_date, total_amount | Уникальность ключа и сумма за закрытую неделю |
| tickets | Одна строка = один билет | book_ref, ticket_no | Число билетов агрегируется до брони |
| Календарь | Один день МСК | Полуоткрытый интервал | Граница в 00:00 не попадает в две недели |
Четыре KPI-карточки и их проверяемый запрос
В верхней полосе поставьте сумму оформленных бронирований за неделю — 3 377 874 800 ₽, число бронирований — 42 561, среднюю сумму одной брони — 79 365,49 ₽ и изменение суммы к предыдущей полной неделе — +8,39%. Предыдущая неделя дала 3 116 503 800 ₽ на 39 216 бронях, среднюю сумму 79 470,21 ₽. Изменение числа броней составляет около +8,53%, среднего чека — около −0,13%; арифметически рост общей суммы почти целиком связан с числом броней, но это ещё не объяснение причины роста спроса.
Подписывайте и величину, и период: «Сумма новых бронирований, 3–9 августа, ₽». Не пишите «продажи сегодня» на недельном отчёте. Карточка изменения должна показывать базу сравнения рядом с процентом; иначе +8,39% не говорит читателю, с чем сравнили. Отсутствие возвратов и оплаты означает, что сумму нельзя трактовать как чистый денежный поток.
Проверьте изменение двумя способами. Прямой расчёт (3 377 874 800 / 3 116 503 800 - 1) × 100 даёт около 8,39%. Разложение общей суммы на число и среднюю стоимость показывает, почему один процент нельзя автоматически назвать «ростом чека»: броней стало больше на 3 345, а средняя сумма снизилась примерно на 104,72 ₽. На панели лучше поставить рядом относительное изменение и абсолютную прибавку 261 371 000 ₽. Если читать только проценты, маленькая база прошлого периода или ошибка выгрузки останутся невидимыми.
Итоговые карточки не нужно считать четырьмя независимыми запросами с разными фильтрами. Создайте один проверенный слой дневных или недельных агрегатов и вычисляйте доли от него. При изменении даты один фильтр должен менять все четыре карточки. Если возвращается пустой период, выводите «данных нет», а не 0 ₽: ноль означает измеренное отсутствие броней, пустота — отсутствие измерения. Это различие становится критичным при сбое загрузки.
| Неделя | Бронирования | Сумма, ₽ | Средняя бронь, ₽ |
|---|---|---|---|
| 27.07–02.08 | 39 216 | 3 116 503 800 | 79 470,21 |
| 03.08–09.08 | 42 561 | 3 377 874 800 | 79 365,49 |
SELECT CASE WHEN book_date >= TIMESTAMP '2026-08-03'
THEN 'текущая' ELSE 'предыдущая' END AS неделя,
COUNT(*) AS бронирования,
SUM(total_amount) AS сумма_руб,
ROUND(AVG(total_amount), 2) AS средняя_бронь_руб
FROM bookings
WHERE book_date >= TIMESTAMP '2026-07-27'
AND book_date < TIMESTAMP '2026-08-10'
GROUP BY 1;Динамика: линия показывает движение, а не причину
Недельная карточка скрывает форму изменения. За 3–9 августа сумма бронирований по дням выросла с 452,16 до 509,63 млн ₽; число броней — с 5 665 до 6 531. Для ежедневной динамики используйте линию, если важна последовательность дней, и подпишите единицу «млн ₽». Таблица под графиком или раскрытие деталей даст точные значения. Не строите линию по пяти случайным строкам из bookings: сначала агрегируйте деньги по дате.
Растущая линия внутри одной недели не доказывает эффект акции или продукта. Возможно, влияет день недели или перенос спроса. Для решения о вмешательстве понадобится сравнить те же дни прошлой недели и проверить доступность рейсов, цены и полноту загрузки. На нашем макете график отвечает только на вопрос «когда изменялась сумма», а следующий разрез — «в каких типах бронирования».
Дни августа 2026, московское время. Числа округлены для графика; запрос и таблицы используют точные рубли.
SELECT CAST(book_date AS DATE) AS день,
COUNT(*) AS бронирования,
SUM(total_amount) AS сумма_руб
FROM bookings
WHERE book_date >= TIMESTAMP '2026-08-03'
AND book_date < TIMESTAMP '2026-08-10'
GROUP BY 1 ORDER BY 1;Разрез: одна бронь или несколько билетов
Один билет содержат 28 011 броней, вместе они дают 1 586 128 300 ₽. В 14 550 бронях есть два и больше билетов; их сумма — 1 791 746 500 ₽, то есть около 53% всей суммы недели. Этот разрез полезен: показывает, что меньшее число многобилетных броней даёт большую часть суммы. Он не говорит, почему неделя выросла; для этого нужен тот же разрез по предыдущей неделе.
Проверка предыдущего периода даёт для одного билета 25 799 броней на 1 460 759 800 ₽, для двух и более — 13 417 на 1 655 744 000 ₽. Прирост суммы одного билета — 125 368 500 ₽, нескольких — 136 002 500 ₽. Оба сегмента внесли близкий вклад. Без этого сравнения легко было бы объявить «виновником» самый крупный сегмент только потому, что он крупный. SQL сначала группирует билеты до book_ref, затем берёт деньги из bookings один раз.
Проверьте разрез на одном book_ref: в ticket_counts он встречается один раз независимо от количества строк в tickets. Если число броней после LEFT JOIN стало больше числа исходных броней, запрос не готов к публикации. Если оно стало меньше после INNER JOIN, часть броней потерялась из-за отсутствующих билетов. Оба отклонения надо вывести отдельно, а не скрывать в группе «прочее». Полная сумма сегментов должна вернуть 3 377 874 800 ₽; это быстрый арифметический тест, который ловит и потери, и размножение.
Когда руководитель увидит большую сумму у многобилетных броней, не называйте её автоматически «корпоративными продажами»: в данных нет признака корпоративного клиента. Тип брони — описательная группировка, достаточная для первого разреза. Для решения о тарифе понадобятся маршрут, класс, дата вылета и, возможно, условия возврата; соединения с ними потребуют отдельного правила распределения полной суммы.
| Тип брони | Прошлая неделя, ₽ | Текущая, ₽ | Прирост, ₽ |
|---|---|---|---|
| 1 билет | 1 460 759 800 | 1 586 128 300 | 125 368 500 |
| 2+ билета | 1 655 744 000 | 1 791 746 500 | 136 002 500 |
Билеты агрегированы до брони; сумма каждой брони учитывается один раз.
WITH ticket_counts AS (
SELECT book_ref, COUNT(*) AS ticket_count
FROM tickets GROUP BY book_ref
)
SELECT CASE WHEN b.book_date >= TIMESTAMP '2026-08-03'
THEN 'текущая' ELSE 'предыдущая' END AS неделя,
CASE WHEN t.ticket_count = 1 THEN '1 билет'
ELSE '2+ билета' END AS тип,
COUNT(*) AS бронирования, SUM(b.total_amount) AS сумма_руб
FROM bookings b JOIN ticket_counts t USING (book_ref)
WHERE b.book_date >= TIMESTAMP '2026-07-27'
AND b.book_date < TIMESTAMP '2026-08-10'
GROUP BY 1, 2 ORDER BY 1, 2;Макет: сверху итог, ниже причина, затем проверяемые детали
Первый экран может состоять из четырёх карточек и одной широкой линии. Следующая строка — разбивка по одному и нескольким билетам; она объясняет состав, а не причинность. Ниже — таблица броней с датой, кодом, суммой и числом билетов. Так читатель начинает с ответа на свой вопрос, при необходимости спускается на уровень проверки, а не ищет главную цифру между шестью диаграммами.
Составьте макет на бумаге до переноса в BI. Для каждой зоны подпишите не название визуала, а вопрос, который он закрывает. Если зона не ведёт к решению и не помогает проверить число, её можно убрать. На телефоне карточки лягут одна под другую; порядок сверху вниз должен сохранять смысл. Не превращайте таблицу деталей в огромный скрин из десятков столбцов — оставьте ссылку на выгрузку или отдельный вопрос.
| Зона | Вопрос | Элемент | Источник |
|---|---|---|---|
| Верх | Выросла ли сумма? | 4 KPI: сумма, число, средняя, изменение | bookings |
| Середина | Когда менялась? | Линия по дням | bookings, GROUP BY день |
| Ниже | Каков состав и вклад? | 2 столбца и таблица сравнения | bookings + tickets, после агрегации |
| Детали | Можно ли сверить? | Брони по ключу и дате | bookings + ticket_count |
Фильтры и периоды: меньше свободы, больше сопоставимости
Оставьте переключатель полной недели и, если заказчик действительно принимает отдельное решение по типу брони, один фильтр «один билет / несколько». Для текущей неполной недели нужен отдельный режим с крупной пометкой о свежести. Не ставьте бесконечный диапазон дат рядом с карточкой «к прошлой неделе»: при произвольном промежутке база сравнения становится неоднозначной.
Синхронизируйте один и тот же период на всех элементах. Иначе верхняя сумма за календарную неделю, линия за семь скользящих дней, а таблица по локальному часовому поясу покажут три верных по отдельности, но несопоставимых ответа. Проверьте границу в полночь и дату 9 августа 23:59:59 на тестовой строке. Полуоткрытый интервал >= 03.08 00:00 и < 10.08 00:00 устраняет двойное попадание на границе.
Проверьте сценарий, когда пользователь выбирает только брони с одним билетом. Процент к прошлой неделе должен пересчитываться на той же группе и обеих полных неделях. Нельзя оставить в знаменателе все прошлые брони и показать результат как изменение однобилетных. В подписях графиков должен отображаться активный фильтр; при выгрузке в PDF или скриншот он иначе потеряется. Для публикации можно зафиксировать стартовый вид «все брони», чтобы два руководителя обсуждали одно и то же значение.
Отдельно решите, что происходит с календарём на границе часовых поясов. Учебный файл уже хранит московское время, но в рабочей системе timestamps часто записываются в UTC. Тогда переводите к зоне бизнеса до группировки по дню, а не после. В противном случае несколько часов около полуночи перейдут в соседний период; итоговая сумма за две недели может совпасть, но дневные графики и недельное сравнение разойдутся.
Как принять работу: сверка до красоты
Сначала сравните сумму и число броней из BI с независимым запросом к bookings без соединений. Затем убедитесь, что сумма сегментов точно равна общей сумме 3 377 874 800 ₽ и что дневные суммы складываются в ту же величину. Проверьте пустой сегмент, дубли book_ref, пропуски даты и суммы. На примере крупной брони раскройте путь от строки источника до карточки. Только после этого подбирайте подписи и интервалы оси.
Следующий тест — действия заказчика. Попросите руководителя за 30 секунд ответить, выросла ли сумма, за счёт объёма или размера брони, и где открыть детали. Если ответ требует вашего устного объяснения, заголовок или порядок элементов не работают. Если пользователь называет сумму «выручкой», вернитесь к подписи: экран подталкивает к неверному выводу. В приёмке фиксируйте не только пиксели, но и эти проверяемые ответы.
Запишите результаты приёмки как набор инвариантов: семь дневных строк; сумма дней равна карточке; сумма групп равна карточке; число броней после сегментации равно 42 561; предыдущая и текущая неделя не пересекаются; средняя равна сумме, делённой на число. Такой список можно выполнять заново после обновления источника. Для больших систем автоматизируйте его; для первого небольшого проекта достаточно сохранённых контрольных запросов и ответственного за их запуск.
Отдельная проверка — правдоподобие. Самая большая бронь учебной недели составляет 1 062 800 ₽; откройте её исходный ключ и убедитесь, что она попала в сумму один раз. Сравните медиану 56 000 ₽ со средней 79 365,49 ₽: длинный правый хвост предупреждает, что «типичную бронь» по средней описывать нельзя. Это не требование ставить все показатели на главный экран, а способ не допустить неподходящую интерпретацию.
| book_ref | Дата МСК | Сумма, ₽ | Билеты |
|---|---|---|---|
| D7E9AA | 04.08 | 1 062 800 | 4 |
| 60061E | 05.08 | 910 600 | 4 |
| C72D7C | 07.08 | 872 900 | 3 |
| 91BC5C | 05.08 | 809 100 | 4 |
| 5D3071 | 06.08 | 803 800 | 4 |
WITH ticket_counts AS (
SELECT book_ref, COUNT(*) AS ticket_count
FROM tickets GROUP BY book_ref
)
SELECT b.book_ref, CAST(b.book_date AS DATE) AS день,
b.total_amount AS сумма_руб, t.ticket_count AS билеты
FROM bookings b JOIN ticket_counts t USING (book_ref)
WHERE b.book_date >= TIMESTAMP '2026-08-03'
AND b.book_date < TIMESTAMP '2026-08-10'
ORDER BY b.total_amount DESC, b.book_ref LIMIT 5;Публикация: доступ, обновление и след ошибки
Назначьте владельца определения метрики и владельца загрузки. На странице должна быть дата и время последнего успешного обновления, а не время, когда пользователь открыл вкладку. Если загрузка не прошла, оставьте прошлую версию с предупреждением; пустую или частичную неделю нельзя молча выдавать за новое состояние. Настройте права по ролям: детальные бронирования могут требовать более узкого доступа, чем агрегированные карточки.
Опишите поведение при исправлении прошлого периода: пересчитать обе недели, обновить процент и сохранить отметку об изменении. В учебной Parquet-базе нет живого расписания загрузок — здесь это критерии для будущей системы, а не обещание, что макет обновляется автоматически. Если отчёт будут экспортировать, сохраните в выгрузке период, единицу и дату данных; цифры без контекста быстро начинают жить отдельно от определения.
На опубликованной странице полезны три даты: конец периода расчёта, время последнего успешного обновления и, если цифры пересчитывались задним числом, дата корректировки. Не сливайте их в одну подпись «обновлено сегодня». Например, панель могла загрузиться сегодня утром, но показывать полную неделю, закрытую в воскресенье; для недельного решения это ожидаемо. Если загрузка частичная, зелёная отметка свежести без контроля числа строк лишь маскирует проблему. В регламенте укажите, кто обнаруживает сбой, кто перезапускает расчёт и как пользователи узнают об исправлении.
Где собрать: Excel, DataLens, Power BI, Superset или Metabase
Выбор начинается с источника, доступа и процесса обновления. Excel подходит небольшой команде и ручной проверке, но совместная публикация и единые определения требуют дисциплины. DataLens описывает подключение, датасеты, чарты и дашборды. Power BI разделяет отчёт в Desktop и дашборд в сервисе. Superset ориентирован на датасеты, Explore и SQL Lab. В Metabase сохранённый вопрос можно добавить на дашборд. Функции и интерфейс сверены по официальным страницам 27 сентября 2026 года; лицензии и доступность уточняйте отдельно.
Ни один из инструментов не исправит отсутствие определения «суммы бронирований». Сначала обеспечьте один слой проверенных агрегатов, затем выберите среду, где его смогут обновлять и обсуждать ваши пользователи. Ниже — роль инструмента в этом сценарии, а не рейтинг «лучших BI».
| Ситуация | Куда смотреть | Почему | Когда не подходит |
|---|---|---|---|
| Одна команда, разовая проверка | Excel | Быстро сверить таблицу и сводные | Нет устойчивого процесса обновления |
| Команда в экосистеме Yandex Cloud | DataLens | Подключение → датасет → чарт → экран | Проверьте доступы и источник |
| Используется модель Power BI | Power BI | Отчёт и сервисная публикация | Уточните условия доступа и лицензии |
| Инженерная команда, SQL и своё размещение | Superset | Датасеты, чарты, SQL Lab | Нужен владелец эксплуатации |
| Нужен быстрый вопрос к БД | Metabase | Конструктор и SQL-вопросы | Проверьте права на детальные данные |
Через месяц: оставить только работающие элементы
Посмотрите, кто открывал страницу, какие фильтры применялись, какие выгрузки всё ещё просят вручную. Нулевая посещаемость сама по себе не доказывает плохой интерфейс: возможно, решение больше не принимают еженедельно. Спросите заказчика, какое действие он сделал по странице за месяц и чего ему не хватило. Если главная карточка стала спорной, исправьте определение и историю расчёта прежде, чем добавлять новые чарты.
Запишите срок пересмотра и критерий удаления. Дашборды обычно растут без ограничения: каждый новый вопрос превращается в ещё один блок. Разовый вопрос лучше решить отчётом; регулярный, но чужой аудитории — отдельной страницей. Так у первой страницы сохраняется один пользователь, одно решение и понятная иерархия.
Сохраните журнал изменений страницы: дату, формулировку показателя, причину правки и затронутые периоды. Когда у команды возникнет вопрос о старом решении, эта запись поможет отделить изменение бизнеса от изменения расчёта. Без истории даже правильная новая цифра выглядит как ошибка.
Восемь ошибок, которые делают дашборд опасным
Первая — назвать стоимость оформленных броней выручкой: руководитель примет решение о деньгах по показателю до возвратов и признания. Вторая — соединить bookings с tickets до суммирования: брони с несколькими билетами попадут в сумму повторно. Третья — смешать полную прошлую неделю с текущей неполной: страница нарисует ложное падение. Четвёртая — дать фильтр, который меняет только один график: пользователь сравнит несопоставимые числа. Пятая — скрыть время загрузки: старые данные будут выглядеть текущими.
Шестая — собрать страницу ради всех отделов сразу, поэтому ни один не увидит свою очередь действий. Седьмая — показать рост без базового периода и абсолютной суммы: +8,39% может оказаться на очень маленькой базе. Восьмая — сделать столбцы без нулевой точки и визуально преувеличить отличие дней. Каждая ошибка ведёт к конкретному неверному действию, поэтому проверяйте макет вопросом: «какое решение здесь может испортиться?»
Частые вопросы и следующий шаг
Как сделать дашборд без программиста? Для небольшой проверенной таблицы начните с Excel или конструктора BI; всё равно нужен человек, который знает зерно, формулы и источник. Сколько графиков должно быть? Столько, сколько нужно для одного решения, обычно немного; фиксированного отраслевого числа нет. Как часто обновлять? По частоте решения и задержке источника, а не по возможностям инструмента. Можно ли взять шаблон? Да, как сетку расположения, но определения метрик и контроль чисел придётся сделать для своих данных.
Возьмите свой повторяющийся вопрос и соберите одну страницу на бумаге: четыре подписанные карточки, один временной ряд, один объясняющий разрез и таблицу проверки. Затем выполните контрольный SQL. Если запрос пока сложен, начните с тренажёра SQL с нуля: на понятных данных легче обнаружить ошибку зерна, чем на готовой красивой панели.
Куда идти дальше по теме BI
Этот хаб отвечает на последовательность работы. Если сначала нужно договориться о значении показателя, откройте KPI и техническое задание. Если хочется понять разницу между платформой и экраном — BI-система и что такое дашборд. Для графиков пригодятся выбор диаграммы, принципы визуализации и визуализация в Python.
Для организации работы — BI-аналитик и собеседование BI-аналитика. Для контроля после запуска — почему дашборд не работает. ИИ может помогать черновиками, но проверку оставляйте за человеком: отдельно разобраны ИИ в BI, нейросеть для графиков и нейросеть для Excel. Практический путь в Excel: сводные таблицы → дашборд → повторяемая подготовка в Power Query. Для работы в BI откройте Yandex DataLens, Power BI и формулы DAX для модели с мерами. Если начинаете с SQL и готового источника, сравните Apache Superset и Metabase: во всех пяти гайдах использована та же учебная неделя и одна контрольная сумма.
Материалы по теме

Примеры дашбордов: продажи, продукт, маркетинг и руководитель
Шесть макетов дашбордов под разные решения: кто смотрит, какие метрики считать, где показать детали и какие ошибки исказят вывод. Два примера — на проверенных данных.

Дашборд в Excel: от сводных таблиц до готового экрана
Собираем дашборд в Excel на одном файле: лист данных, сводные, KPI, диаграммы, общие срезы, проверка итогов и безопасное обновление.

Дашборд: что это такое, из чего состоит и какие бывают
Дашборд — это страница с несколькими регулярно обновляемыми показателями для одного решения. Чем он отличается от отчёта и BI-системы, какие бывают дашборды, из чего состоят и как посчитать KPI-карточки на SQL.