Compare commits
4
Commits
7a002f4d5a
...
515f386e5f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
515f386e5f | ||
|
|
2502277af1 | ||
|
|
ddb186f841 | ||
|
|
090df8a715 |
No files matched your search
@@ -46,15 +46,10 @@
|
||||
|
||||
## Кому что поручать
|
||||
|
||||
Читатель здесь не побочный потребитель, а тот, ради кого стенд существует:
|
||||
код, комментарии и документы и есть продукт. Поэтому всё, что человек будет
|
||||
читать и разбирать, пишет модель с чувством меры — сейчас это Opus. Codex
|
||||
берёт техническую работу без вкусовых решений: миграции, разбор журналов и
|
||||
объёмного вывода, обход репозитория, повторяющиеся правки. Там его запас
|
||||
лимитов работает на нас, а экономить их на читаемом коде — экономия ложная:
|
||||
переписывать выйдет дороже, чем сразу написать хорошо.
|
||||
Автор задачи сам пишет и редактирует код, комментарии и документы, если
|
||||
владелец не задал другое распределение работы.
|
||||
|
||||
Делить работу между ними стоит не целыми задачами, а подзадачами, и решать
|
||||
Делить работу стоит не целыми задачами, а подзадачами, и решать
|
||||
это при планировании. Вкусовая часть идёт первой: она задаёт форму, имена и
|
||||
границы, под которые механическая потом подстраивается.
|
||||
|
||||
|
||||
+13
-2
@@ -124,8 +124,19 @@ DM](../architecture/dm.md).
|
||||
|
||||
### Почему выручка не сходится
|
||||
|
||||
Открывается после ступени 1. Расхождения между источниками, повторы
|
||||
покупок и день, после которого отчет можно считать окончательным.
|
||||
Открывается после ступени 1. Четыре расследования:
|
||||
|
||||
- [Куда пропали покупки](optional/missing-purchases.md): найти заказы без
|
||||
события в трекере и объяснить разрыв воронки.
|
||||
- [Почему повтор покупки завышает выручку](optional/duplicate-purchases.md):
|
||||
посчитать деньги по номеру заказа и объяснить вклад повторов.
|
||||
- [Какая позиция объясняет разницу в сумме](optional/order-amount-difference.md):
|
||||
сопоставить корзины и найти причину расхождения до копейки.
|
||||
- [Почему вчерашняя выручка меняется сегодня](optional/revenue-over-time.md):
|
||||
проследить опоздания и отмены, затем определить момент закрытия дня.
|
||||
|
||||
Первые три работы используют готовые данные. Четвертая продвигает мир через
|
||||
Airflow; для нее вы сохраняете состояния заказов после каждого модельного дня.
|
||||
|
||||
### Тонкий анализ данных
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
# Почему повтор покупки завышает выручку
|
||||
|
||||
**Чему учит:** отличать повторную доставку строки от повторного события об
|
||||
одной покупке и выбирать ключ, по которому считать деньги.
|
||||
|
||||
Факультатив доступен после ступени 1. Работайте в DBeaver пользователем
|
||||
`analyst` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; оставьте `world_live` на паузе и
|
||||
дождитесь уже начатых прогонов, чтобы данные не менялись между запросами.
|
||||
|
||||
## Посчитайте клиентскую сумму двумя способами
|
||||
|
||||
Возьмите один закрытый день: его дата должна быть не позднее
|
||||
`max(snapshot_date) - 6` из `ods.order_v`. Во всех запросах к `dds.event_v`
|
||||
отбирайте этот `event_date` и `event_type = 'purchase'`.
|
||||
|
||||
Номер заказа находится в `purchase_id[1]`, заявленная сумма — в
|
||||
`purchase_revenue[1]`. По формату источника у события покупки один номер заказа.
|
||||
|
||||
Сначала посчитайте число событий и сумму всех заявленных сумм. Затем найдите
|
||||
номера заказов, которые встречаются несколько раз. Если таких нет, выберите
|
||||
другой закрытый день.
|
||||
|
||||
Для двух повторившихся покупок выпишите `event_id`, `client_id`, `event_time`,
|
||||
номер заказа и сумму. Сопоставьте число событий и заказов в `dds.order_v`.
|
||||
|
||||
Теперь рассчитайте клиентскую сумму, учитывая каждый номер заказа один раз.
|
||||
До выбора одной суммы на заказ проверьте, что во всех его событиях она
|
||||
одинакова. Объясните, почему удалять одинаковые денежные значения вместо
|
||||
повторных номеров заказов было бы ошибкой.
|
||||
|
||||
## Объясните разницу
|
||||
|
||||
Для каждого повторившегося заказа определите число лишних событий и их
|
||||
вклад в завышение. Сложите эти вклады и сверьте с разностью двух расчетов.
|
||||
Равенство должно выполняться до копейки.
|
||||
|
||||
Слой ODS убирает повторную доставку одного события по его идентификатору;
|
||||
`dds.event_v` читает уже это состояние. Объясните по своим строкам, почему
|
||||
повтор покупки сохранился. Какие поля совпадают и какие различаются?
|
||||
Какой ключ отвечает на вопрос «это то же событие», а какой — «это тот же заказ»?
|
||||
|
||||
После собственного расчета найдите эти заказы в `dm.purchase_vs_orders_v`.
|
||||
Если у повторившегося заказа класс отличается от `duplicate_event`, проверьте
|
||||
его статус и [порядок присвоения классов](../../architecture/dm.md#dmpurchase_vs_orders_v).
|
||||
Класс витрины не заменяет поиск всех повторов в событиях.
|
||||
|
||||
## Сравните с выручкой магазина
|
||||
|
||||
Сложите `revenue` из `dm.revenue_daily_v` за тот же `report_date` по всем
|
||||
категориям. Эта витрина считает стоимость позиций оплаченных заказов,
|
||||
без скидки и доставки.
|
||||
|
||||
Сравните результат с исправленной клиентской суммой. Совпадение не требуется:
|
||||
удаление повторов устраняет одну причину расхождения. Найдите хотя бы один
|
||||
заказ, который объясняет, почему деньги трекера и магазина все еще могут
|
||||
различаться. Для этого сопоставьте события, заказ и готовую сверку.
|
||||
|
||||
## Что должно получиться
|
||||
|
||||
- [ ] сохранены две клиентские суммы и строки повторившихся покупок;
|
||||
- [ ] разность сумм полностью объяснена вкладом лишних событий;
|
||||
- [ ] выбор ключа для устранения повторов подтвержден данными;
|
||||
- [ ] вы можете объяснить, почему устранение повторов не завершает сверку
|
||||
выручки с магазином.
|
||||
@@ -0,0 +1,79 @@
|
||||
# Куда пропали покупки
|
||||
|
||||
**Чему учит:** обнаружить потерю событий при сверке двух источников и
|
||||
обосновать, каким данным можно доверять при подсчете покупок.
|
||||
|
||||
Факультатив доступен после ступени 1. В DBeaver подключитесь пользователем
|
||||
`analyst` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; на время расследования оставьте
|
||||
`world_live` на паузе и дождитесь уже начатых прогонов.
|
||||
|
||||
## Выберите день
|
||||
|
||||
Магазин зарегистрировал заказы, но часть событий покупки не дошла до трекера.
|
||||
Найдите след этой потери сначала в событиях сайта, затем в заказах.
|
||||
|
||||
Возьмите день, для которого уже получен последний слепок семидневного окна.
|
||||
Запрос показывает самую позднюю подходящую дату:
|
||||
|
||||
```sql
|
||||
SELECT max(snapshot_date) - 6 AS last_closed_day
|
||||
FROM ods.order_v;
|
||||
```
|
||||
|
||||
Используйте выбранный день во всех запросах. События отбирайте по
|
||||
`dds.event_v.event_date`, заказы — по `dds.order_v.order_date`.
|
||||
Сравнивайте все заказы дня, включая отмененные: сейчас вопрос в том,
|
||||
зарегистрировал ли магазин заказ, а не в том, был ли он оплачен.
|
||||
|
||||
## Найдите разрыв в событиях
|
||||
|
||||
Посчитайте просмотры страницы подтверждения и события покупки:
|
||||
|
||||
- у просмотра `event_type = 'pageview'`, а `url` заканчивается на `/confirmation`;
|
||||
- у покупки `event_type = 'purchase'`.
|
||||
|
||||
Запишите оба числа и разность. Какую потерю она позволяет заподозрить?
|
||||
Достаточно ли этих двух чисел, чтобы назвать пропавшие покупки?
|
||||
|
||||
## Сверьте с магазином
|
||||
|
||||
В событии номер заказа находится в `purchase_id[1]`, в заказах — в `order_id`.
|
||||
Соберите список заказов выбранного дня, для которых нет события покупки.
|
||||
Несколько событий с одним номером заказа должны оставаться одной покупкой.
|
||||
|
||||
Проверьте два равенства:
|
||||
|
||||
- число заказов магазина равно числу разных заказов из событий плюс число
|
||||
заказов без события;
|
||||
- разность просмотров подтверждения и событий покупки равна числу заказов
|
||||
без события.
|
||||
|
||||
Первое равенство проверяет полноту сопоставления источников. Второе относится
|
||||
к устройству этого стенда. Найдите покупку с повторным событием и посмотрите
|
||||
соседние события того же `client_id` по времени: что произошло со страницей
|
||||
подтверждения? Объясните, почему повтор не скрыл разрыв воронки.
|
||||
|
||||
Если в выбранном дне повторов нет, возьмите другой закрытый день.
|
||||
Для оценки доли потерь используйте число заказов магазина и объясните,
|
||||
почему число просмотров подтверждения может дать другую долю.
|
||||
|
||||
## Сопоставьте вывод с готовой сверкой
|
||||
|
||||
Найдите свои заказы без события в `dm.purchase_vs_orders_v` по `order_id`.
|
||||
Сравните их `status` и `mismatch_class`. Витрина присваивает заказу один класс,
|
||||
хотя причин расхождения может быть несколько. По
|
||||
[правилу классификации](../../architecture/dm.md#dmpurchase_vs_orders_v)
|
||||
объясните, почему потеря события не всегда попадает в `lost_event`.
|
||||
|
||||
Возьмите один заказ из своего списка и сохраните два запроса: первый находит
|
||||
его в магазине, второй показывает отсутствие покупки в трекере. Сформулируйте,
|
||||
какой источник нужен для отчета о поведении посетителей, а какой — для денег.
|
||||
|
||||
## Что должно получиться
|
||||
|
||||
- [ ] сохранены день, счетчики воронки и список заказов без события;
|
||||
- [ ] оба равенства сходятся, влияние повторного просмотра объяснено;
|
||||
- [ ] доля потерь посчитана с обоснованным знаменателем;
|
||||
- [ ] один случай подтвержден запросами к обоим источникам;
|
||||
- [ ] вы различаете отсутствие события и класс строки в готовой сверке.
|
||||
@@ -0,0 +1,70 @@
|
||||
# Какая позиция объясняет разницу в сумме
|
||||
|
||||
**Чему учит:** перейти от расхождения суммы заказа к конкретному товару и
|
||||
проверить объяснение с точностью до копейки.
|
||||
|
||||
Факультатив доступен после ступени 1. В DBeaver используйте пользователя
|
||||
`analyst` из [инструкции подключения](../../../README.md#подключиться-из-dbeaver).
|
||||
Дождитесь завершения `etl_pipeline`; оставьте `world_live` на паузе и
|
||||
дождитесь уже начатых прогонов.
|
||||
|
||||
## Найдите заказ
|
||||
|
||||
В `dm.purchase_vs_orders_v` выберите один заказ с
|
||||
`mismatch_class = 'amount_delta'`. Возьмите закрытый день: `order_day`
|
||||
не позднее `max(snapshot_date) - 6` из `ods.order_v`. Сохраните `order_id`,
|
||||
`order_day`, `declared_revenue` и `items_total`.
|
||||
|
||||
Найдите этот заказ в `dds.order_v`. Сопоставьте `items_total`, `discount`,
|
||||
`delivery` и `total`. Как связаны эти суммы? Объясните, почему клиентскую
|
||||
`declared_revenue` нужно сравнивать с `items_total`, чтобы искать разницу
|
||||
именно в составе корзины.
|
||||
|
||||
## Разберите позиции с двух сторон
|
||||
|
||||
Найдите событие покупки в `ods.event_v`: `purchaseID[1]` совпадает с номером
|
||||
заказа, `EventDate` — с выбранным днем, `EventType = 'purchase'`.
|
||||
Откройте поле `ecommerce`. Внутри JSON массив `purchase.products` содержит
|
||||
позиции клиента с полями `id`, `price` и `quantity`.
|
||||
|
||||
Разверните этот массив в строки и получите артикул, точную цену, количество
|
||||
и стоимость каждой позиции. Для разбора пригодятся `JSONExtractArrayRaw`
|
||||
и `JSONExtract`, для разворачивания массива — `ARRAY JOIN`.
|
||||
Деньги извлекайте как `Decimal` с двумя знаками после запятой.
|
||||
|
||||
С другой стороны используйте массивы `item_sku`, `item_price` и
|
||||
`item_quantity` заказа в `dds.order_v`. Элементы с одним индексом относятся
|
||||
к одной позиции; при разворачивании сохраняйте эту связь.
|
||||
|
||||
Сопоставьте позиции по артикулу так, чтобы остались видны товары,
|
||||
присутствующие только с одной стороны. Покажите, какие позиции совпали,
|
||||
а какая объясняет разницу. В результате нужны строки товаров, а не только
|
||||
две итоговые суммы.
|
||||
|
||||
## Проверьте объяснение
|
||||
|
||||
Подтвердите три равенства:
|
||||
|
||||
- сумма стоимостей клиентских позиций равна `declared_revenue`;
|
||||
- сумма стоимостей позиций магазина равна `items_total`;
|
||||
- стоимость отсутствующей у магазина позиции равна
|
||||
`declared_revenue - items_total`.
|
||||
|
||||
Затем сравните точные цены из JSON с готовым массивом `productPrice`
|
||||
события. По [формату выгрузки](../../formats/clickstream-event.md) цены в нем
|
||||
округлены до целых рублей. Покажите на своей корзине, что потеряется при
|
||||
расчете по этому массиву. Если все цены выбранной корзины целые, возьмите
|
||||
еще один заказ с расхождением и дробной ценой.
|
||||
|
||||
В коротком объяснении назовите заказ, товар, количество, цену и разницу.
|
||||
Отделите то, что подтверждают данные, от причины, которую по ним установить
|
||||
нельзя: отсутствие позиции в заказе видно, а причину ее удаления источник
|
||||
отдельным полем не сообщает.
|
||||
|
||||
## Что должно получиться
|
||||
|
||||
- [ ] позиции клиента и магазина сопоставлены по артикулам;
|
||||
- [ ] все три равенства сходятся до копейки;
|
||||
- [ ] найден пример потери точности в готовом массиве цен;
|
||||
- [ ] расхождение объяснено конкретной позицией, а скидка и доставка
|
||||
отделены от сравнения корзин.
|
||||
@@ -0,0 +1,131 @@
|
||||
# Почему вчерашняя выручка меняется сегодня
|
||||
|
||||
**Чему учит:** объяснять изменения уже рассчитанного отчета поступлением
|
||||
заказов и сменой их статусов, определять момент закрытия дня и границы
|
||||
доступной истории.
|
||||
|
||||
Факультатив доступен после ступени 1. Понадобятся Airflow и DBeaver с
|
||||
подключением `analyst` по [инструкции](../../../README.md#подключиться-из-dbeaver).
|
||||
Вы будете наблюдать один день оформления заказов, продвигая мир по одному
|
||||
модельному дню. Новые данные останутся в стенде.
|
||||
|
||||
## Подготовьте первое наблюдение
|
||||
|
||||
Поставьте `world_live` на паузу. Дождитесь завершения начатых прогонов
|
||||
генерации и обработки, затем запустите `etl_pipeline` и дождитесь успеха.
|
||||
Так исходное наблюдение будет снято после обновления витрин.
|
||||
|
||||
Узнайте последний день событий и дату последнего полученного слепка:
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
(SELECT max(event_date) FROM dds.event_v) AS event_day,
|
||||
(SELECT max(snapshot_date) FROM ods.order_v) AS snapshot_day;
|
||||
```
|
||||
|
||||
День `event_day` обозначим **D**. Наблюдайте именно его до конца работы.
|
||||
Дата слепка, по которому сделано очередное наблюдение, будет **S**.
|
||||
Это модельные даты магазина. Календарная дата запуска Airflow день D не задает.
|
||||
|
||||
Слепок снимается к концу суток и доставляется следующим прогоном. Поэтому
|
||||
покупки последнего сыгранного дня уже видны в событиях, а их заказов в
|
||||
хранилище еще нет. Проверьте это для D в `dds.order_v` и
|
||||
`dm.purchase_vs_orders_v`.
|
||||
|
||||
## Подготовьте запросы и сохраняйте результаты
|
||||
|
||||
Напишите запросы для следующих наблюдений:
|
||||
|
||||
| Что сохранить | Откуда взять |
|
||||
|---|---|
|
||||
| Дату полученного слепка S | `max(snapshot_date)` из `ods.order_v` |
|
||||
| Номер, статус и `items_total` каждого заказа дня D | `dds.order_v`, отбор по `order_date` |
|
||||
| Число заказов в каждом статусе и сумму `items_total` только у `paid` | те же заказы дня D |
|
||||
| Выручку дня D | сумма `revenue` из `dm.revenue_daily_v`, отбор по `report_date` |
|
||||
| Номера покупок, еще ожидающих заказ | строки `awaiting_order` из `dm.purchase_vs_orders_v`, отбор по `order_day` |
|
||||
|
||||
Выручку складывайте по всем категориям. В этой витрине она означает стоимость
|
||||
позиций оплаченных заказов, без скидки и доставки, поэтому должна сходиться
|
||||
с суммой `items_total` у заказов в статусе `paid`.
|
||||
|
||||
Сохраняйте результаты запросов отдельными файлами, например выгрузками CSV
|
||||
из DBeaver. Подписывайте D и S. До поступления первого слепка список заказов
|
||||
пуст, а выручка равна нулю; сохраните и это наблюдение.
|
||||
|
||||
Публичное представление заказа показывает текущее состояние, а сырые слепки
|
||||
хранятся ограниченное время. Сохраненные выгрузки — история для расследования.
|
||||
|
||||
## Продвигайте мир по одному дню
|
||||
|
||||
Для каждого следующего наблюдения:
|
||||
|
||||
1. Запустите `world_next_day` с `days = 1` и дождитесь успеха.
|
||||
2. Запустите `etl_pipeline` и дождитесь успеха: `world_next_day` сам витрины
|
||||
не обновляет.
|
||||
3. Повторите свои запросы и сохраните новый комплект результатов с датой S.
|
||||
|
||||
Во всех запросах остается прежний день D. За один запуск проигрывайте один
|
||||
день, чтобы сохранить промежуточные состояния. Пакетный `world_next_day`
|
||||
отправляет события без пауз; ждать 24 минуты живого дня здесь не нужно.
|
||||
|
||||
Продолжайте до слепка **D + 7** включительно. У заказов дня D окно состоит
|
||||
из семи дней, от D до D + 6. Слепок D + 6 содержит окончательное состояние,
|
||||
а еще один шаг позволит проверить, что оно сохранилось за пределами окна.
|
||||
От исходного наблюдения потребуется восемь однодневных запусков.
|
||||
|
||||
## Объясните изменения отчета
|
||||
|
||||
После каждого шага сравнивайте заказы по `order_id`, а не по положению строк
|
||||
в выгрузке. Найдите:
|
||||
|
||||
- заказы, отсутствовавшие в первом слепке D, но появившиеся в следующем;
|
||||
- переходы из `created` в `paid`;
|
||||
- отмены заказов, для которых раньше был виден статус `paid`.
|
||||
|
||||
Первый слепок, полученный на следующий день, — обычная доставка заказов.
|
||||
Опоздавшими здесь считаются те, которых не было уже в этом слепке.
|
||||
Покажите на нескольких номерах, как они исчезают из `awaiting_order`.
|
||||
|
||||
Для двух соседних наблюдений разложите изменение выручки по заказам.
|
||||
Вклад заказа — его `items_total`, если статус `paid`, и ноль в остальных
|
||||
случаях, включая отсутствие заказа. Разность вкладов объясняет, сколько
|
||||
каждый заказ добавил к отчету или убрал из него. Сумма этих изменений должна
|
||||
совпасть с изменением `revenue` до копейки.
|
||||
|
||||
Запишите даты, между которыми выручка выросла или уменьшилась. Отдельный
|
||||
отмененный заказ мог убрать деньги, даже если итог дня вырос: покажите это
|
||||
по его вкладу. Одна общая сумма скрывает встречные изменения.
|
||||
|
||||
## Что известно об отменах
|
||||
|
||||
Возьмите отмененный заказ, у которого в вашей истории был статус `paid`.
|
||||
Укажите два наблюдения, доказывающих, что он был оплачен, а затем отменен.
|
||||
|
||||
Для отмененного заказа без наблюдаемой оплаты сформулируйте предел вывода.
|
||||
Дневные слепки могли не застать промежуточное состояние: оплата и отмена
|
||||
могли произойти между ними. Поэтому отсутствие `paid` в выгрузках не
|
||||
доказывает, что оплаты не было. Не заменяйте недостающие данные догадкой.
|
||||
|
||||
## Когда день закрыт
|
||||
|
||||
Сравните сохраненные состояния при S = D + 6 и S = D + 7: состав заказов,
|
||||
их статусы, суммы и выручку. Объясните, почему отчет за D теперь окончательный.
|
||||
Основание — получен и обработан последний слепок окна изменяемости;
|
||||
одно совпадение сумм в соседних наблюдениях этого не доказывает.
|
||||
|
||||
После собственных выводов сверьтесь с описанием
|
||||
[слепка и его доставки](../../architecture/orders/snapshot.md#слепок-и-его-доставка)
|
||||
и [границ истории отмен](../../architecture/orders/fate.md#судьба-заказа).
|
||||
|
||||
## Что должно получиться
|
||||
|
||||
- [ ] сохранена последовательность наблюдений одного дня D с датами слепков S;
|
||||
- [ ] найдены опоздавшие заказы и изменения статусов;
|
||||
- [ ] изменение выручки между двумя наблюдениями объяснено вкладами заказов;
|
||||
- [ ] оплата одной из последующих отмен подтверждена двумя наблюдениями;
|
||||
- [ ] вы различаете доказанную оплату и отсутствие сведений о ней;
|
||||
- [ ] состояние дня за пределами окна совпало с окончательным, а момент
|
||||
закрытия обоснован правилом доставки слепков.
|
||||
|
||||
После работы оставьте `world_live` на паузе либо верните автоматическое
|
||||
продвижение, если пользовались им до наблюдения.
|
||||
@@ -149,28 +149,40 @@
|
||||
|
||||
## 4. Факультативы — пять разделов
|
||||
|
||||
Ниже перечислены только названия сюжетов и их уроки. Материал, формы и способы
|
||||
проверки остаются в [инвентаризации](../research/2026-08-31-labs-inventory.md).
|
||||
Ниже перечислены сюжеты, их уроки и принятые решения по форме заданий. Исходный
|
||||
материал и способы проверки — в
|
||||
[инвентаризации](../research/2026-08-31-labs-inventory.md).
|
||||
|
||||
### Почему выручка не сходится
|
||||
|
||||
Этот раздел рекомендован первым из факультативов. Он открывается после ступени
|
||||
1 основной программы: материал живет на стенде с этапа 6.
|
||||
Этот раздел рекомендован первым из факультативов и открывается после ступени
|
||||
1 основной программы. Шесть сюжетов собраны в четыре лабораторные: три
|
||||
расследования готовых данных и одно наблюдение во времени. Опоздания,
|
||||
изменение выручки и история отмен используют одну историю заказов, поэтому
|
||||
для них выбрана общая работа вместо трех отдельных.
|
||||
|
||||
- **Почему трекер недосчитывает покупки (#186).** Разрыв воронки подтверждений
|
||||
показывает потерянные события и границу доверия к двум источникам.
|
||||
- **Почему повтор покупки завышает выручку (#187).** Движок убирает технический
|
||||
дубль строки, а повтор одной покупки приходится находить по деловому ключу.
|
||||
- **Какая позиция объясняет разницу в сумме.** Расхождение суммы нужно
|
||||
разложить до конкретной вычеркнутой позиции и объяснить до копейки.
|
||||
- **Был ли отмененный заказ оплачен.** Текущее состояние не заменяет историю, а
|
||||
некоторые различия после истечения срока хранения сырых данных уже не
|
||||
восстановить.
|
||||
- **Когда отчет за день можно считать окончательным (#188).** Отчет за день
|
||||
становится окончательным лишь после того, как источник больше не может
|
||||
изменить этот день.
|
||||
- **Почему выручка за день еще меняется.** Внутри окна изменяемости выручка
|
||||
движется, а после закрытия дня фиксируется.
|
||||
- **[Куда пропали покупки](../labs/optional/missing-purchases.md) (#186).**
|
||||
Учащийся объясняет разрыв воронки заказами, для которых нет события покупки.
|
||||
- **[Почему повтор покупки завышает выручку](../labs/optional/duplicate-purchases.md) (#187).**
|
||||
Разность клиентских сумм объясняется повторными событиями одной покупки.
|
||||
- **[Какая позиция объясняет разницу в сумме](../labs/optional/order-amount-difference.md).**
|
||||
Сравнение позиций из исходного JSON и заказа объясняет расхождение до копейки.
|
||||
- **[Почему вчерашняя выручка меняется сегодня](../labs/optional/revenue-over-time.md) (#188).**
|
||||
История одного дня связывает опоздания, оплату и отмены с изменением выручки,
|
||||
позволяет определить момент закрытия дня и границу знания об оплате.
|
||||
|
||||
В четвертой лабораторной выбрано собственное наблюдение: учащийся продвигает
|
||||
мир по одному дню через Airflow и сохраняет результаты после обновления витрин.
|
||||
Готовые слепки и сочетание готового примера с собственным наблюдением
|
||||
отклонены: нужную историю можно получить на стенде и самому увидеть,
|
||||
как новые данные меняют уже рассчитанный отчет.
|
||||
|
||||
День считается закрытым после получения и обработки последнего слепка
|
||||
семидневного окна изменяемости; этот слепок доставляется следующим модельным
|
||||
днем. Одного совпадения сумм в соседних наблюдениях для такого вывода
|
||||
недостаточно. История отмен тоже имеет границу: оплата и отмена между двумя
|
||||
дневными слепками могут остаться невидимыми. Отсутствие наблюдаемой оплаты
|
||||
не доказывает, что оплаты не было.
|
||||
|
||||
### Тонкий анализ данных
|
||||
|
||||
|
||||
Reference in new issue
Block a user