Files
clickstream-data-platform/docs/labs/1-5-utm-effectiveness.md
T
ddadmin 4693bc5af9 docs(labs): упрощен язык учебных заданий
- Зачем: начинающим трудно читать задания из-за необъясненных терминов и неестественных формулировок.
- Что: переработаны вводная и 21 задание, названы темы разделов, объяснены термины и сокращены повторы; согласованы правила учебного текста и ссылки.
- Проверка: сохранены 25 блоков SQL и команд и таблицы состава колонок; проверены 153 локальные ссылки и 32 входящие ссылки на разделы; git diff --check прошел.
2026-10-18 18:09:43 +02:00

147 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Задание 5: показатели рекламы, `dm.utm_effectiveness`
Вы подготовите показатели рекламных каналов по событиям сайта. Суммы покупок
в этой витрине будут отличаться от выручки по заказам магазина. В конце
работы вы сравните их и объясните причины расхождения.
## Подготовка
- [«Хранилище и его слои»](../handbook/storage-layers.md);
- [«Потоки Airflow и даги модельного времени»](../handbook/airflow-dags.md).
## Покупки по рекламным каналам
Аналитик сравнивает рекламные каналы по дням: трафик, добавления в корзину,
покупки и их суммы из событий сайта.
События сайта показывают действия посетителя и рекламные метки его переходов.
Заказы магазина служат источником выручки. Но в заказах нет UTM-меток, поэтому
в этой витрине вы возьмете суммы из событий покупки. Их передает браузер
посетителя; дальше они называются клиентскими суммами. Приставка `declared_`
в имени показателя напоминает об этом источнике.
## Создание витрины
Читайте события из `dds.event_v`, без других витрин DM. В результате нужна
одна строка на день и сочетание трех меток: `utm_source`, `utm_medium`,
`utm_campaign`. События одного дня с одинаковыми метками попадают в одну группу.
Создайте пять объектов по [общим правилам ступени 1](README.md#создание-и-обновление-витрин):
- основные таблицы `dm.utm_effectiveness_rep` и `dm.utm_effectiveness_dist`;
- промежуточные таблицы `dm.utm_effectiveness_stage_rep` и `dm.utm_effectiveness_stage_dist`;
- представление для чтения `dm.utm_effectiveness_v`.
Разбейте данные на партиции по дням.
### Состав колонок
| Колонка | Тип | Значение |
|---|---|---|
| `report_date` | `Date` | День события |
| `utm_source` | `LowCardinality(String)` | Источник кампании |
| `utm_medium` | `LowCardinality(String)` | Канал кампании |
| `utm_campaign` | `String` | Имя кампании |
| `visitors` | `UInt64` | Число разных `client_id` |
| `pageviews` | `UInt64` | Число просмотров страниц |
| `add_to_carts` | `UInt64` | Число добавлений в корзину |
| `purchases` | `UInt64` | Число покупок |
| `declared_revenue` | `Decimal(18, 2)` | Сумма покупок, заявленная клиентом |
| `_load_id` | `String` | Идентификатор запуска, собравшего день |
| `_load_ts` | `DateTime64(3, 'UTC')` | Время сборки |
Для `declared_revenue` сложите `purchase_revenue[1]` событий `purchase`. В
параллельных массивах `purchase*` хранятся один номер заказа и
одна сумма на событие. В сверке `purchase_vs_orders` используют тот же
индекс.
Тип `purchase_revenue` — `Array(Decimal(18, 2))`: исходный `Float64`
преобразован в ODS. Сложение Decimal точное; `CAST` до или после `sum` не
меняет результат и не нужен. Тип итога — `Decimal(18, 2)`.
Для `utm_campaign` выбран тип `String`: имен кампаний со временем становится
много, и затраты на словарь `LowCardinality` перестают окупаться.
### Дни для пересчета
События завершившегося модельного дня больше не меняются. Как в задании 2,
найдите первый завершившийся день, которого еще нет в витрине. Рассчитайте
все дни от него до последнего завершившегося, запишите их в промежуточную
таблицу и замените дневные партиции основной. Добавьте задачу в `dm_transform`.
### Ключ шардирования
Выберите ключ самостоятельно. Если берете хеш одной из трех UTM-колонок,
посчитайте долю строк с ее самым частым значением и обоснуйте выбор.
У основной и промежуточной таблиц должен быть одинаковый ключ шардирования:
см. [общие правила ступени 1](README.md#создание-и-обновление-витрин).
## Рекламные метки событий
Группируйте события по их собственным меткам. Модели «первое касание» и
«последнее касание» здесь не рассчитываются.
В `dds.session_v` записаны UTM первого события визита. Распределение по
каналам может отличаться от этой витрины, и это не означает ошибку в
расчете. Укажите в отчете, что распределяете по рекламным каналам отдельные
события. Такое распределение называют атрибуцией.
## События без рекламных меток
Сохраните события без меток: прямой трафик обычно крупнейший канал, и без
него доля рекламы будет завышена. Если отфильтровать такие строки, дневные
итоги перестанут сходиться с источником — а по этому совпадению вы
проверяете сборку. Разница составит вклад исключенных событий.
Оставьте пустые метки пустыми строками: новое обозначение прямого трафика
потребовало бы объяснения.
## Расхождение с `dm.revenue_daily_v`
Сравните за один день `sum(declared_revenue)` своей витрины и `sum(revenue)`
из `dm.revenue_daily_v`. Суммы не сходятся; проверять их равенство не нужно.
В `revenue_daily` складываются цены позиций, умноженные на количество, без
скидок и доставки — та же основа, что у клиентской суммы. Расхождение
объясняется историей заказов, а не способом расчета:
- событие покупки остается после отмены заказа, а `revenue_daily` учитывает
только оплаченные заказы;
- событие покупки может потеряться при доставке, хотя заказ поступил, или
поступить дважды;
- клиентская сумма может отличаться от серверной суммы позиций: генератор
намеренно создает это расхождение у одного-двух заказов из ста.
Запишите свой вывод в двух-трех фразах. Число расхождений по заказам и их
причины можно посмотреть в `dm.purchase_vs_orders_v`, где выделены классы
расхождений.
## Проверка результата
Рассчитайте те же показатели по `dds.event_v` за выбранный день.
Сопоставьте результат со строками `dm.utm_effectiveness_v` за этот день
через `FULL OUTER JOIN` по `utm_source`, `utm_medium` и `utm_campaign`.
Найдите сочетания меток, которые есть только с одной стороны, и строки,
где различается хотя бы один из пяти показателей. Расхождений должно быть ноль.
Дополнительно сверьте дневные итоги:
- суммы `pageviews`, `add_to_carts` и `purchases` равны числу событий
соответствующих типов в `dds.event_v`;
- сумма `declared_revenue` равна сумме `purchase_revenue[1]` по всем
событиям `purchase` того же дня.
Сумма `visitors` по строкам повторно учитывает одного посетителя,
приходящего по разным меткам. Для числа посетителей дня она не подходит.
## Результат работы
- [ ] у вас есть пять объектов витрины; промежуточная таблица объявлена через
`AS` и использует ключ шардирования основной;
- [ ] строки без UTM-меток сохранены, а `declared_revenue` хранится
в `Decimal(18, 2)`;
- [ ] вы записали, почему сумма отличается от `dm.revenue_daily_v`;
- [ ] проверка `utm_effectiveness` в `homework_check` прошла успешно;
- [ ] витрина обновляется при запуске `dm_transform`.