# Нарежьте сессии сами **Чему учит:** собрать сессии из событий, сравнить их число с `VisitID` источника и найти события, из-за которых расчеты расходятся. ## Сначала прочитать - [Хранилище и его слои, раздел DDS](../handbook/storage-layers.md#dds-язык-бизнеса); - [формат события: Идентификаторы и время](../formats/clickstream-event.md#идентификаторы-и-время). ## Для чего нужны сессии Визит, или сессия, объединяет действия посетителя за один заход на сайт. По визитам аналитик считает длительность и глубину просмотра. В хранилище сессии собираются из отдельных событий. Сверьте самостоятельный расчет с `VisitID`, чтобы увидеть, как из событий получается сессия. ## Что сделать ### Нарезка В SQL Lab или DBeaver под `analyst` напишите запрос к `ods.event_v`. Для своей нарезки и эталона возьмите одни и те же строки за все доступные дни: для расследования понадобятся события соседних дней. Выберите `ClientID`, `UTCEventTime`, `EventDate`, `EventType` и `VisitID`. В `dds.event_v` эталонного `VisitID` нет. Для начала считайте визитом последовательные события одной куки (`ClientID`); пауза дольше 30 минут открывает новый визит. Учитывайте события всех типов. Упорядочите их по `UTCEventTime`. Присвойте каждому событию номер своей сессии внутри куки. Подсказка: оконные функции. Днем сессии считайте `EventDate` ее первого события: дата из `UTCEventTime` отличается от `EventDate` для части событий, поэтому берите `EventDate`. При сверке останутся расхождения из-за еще одной договоренности стенда. ### Сверка с эталоном В эталоне посчитайте число визитов каждой куки за модельный день: ```sql SELECT ClientID, EventDate, uniqExact(VisitID) AS reference_sessions FROM ods.event_v GROUP BY ClientID, EventDate ORDER BY EventDate, ClientID; ``` Посчитайте свои сессии по куке и дню сессии. Соедините два готовых агрегата через `FULL OUTER JOIN` по куке и дню. В результате полного соединения останутся ключи обеих сторон: при расхождении на вашей стороне ключа может не быть совсем. Учтите такие строки при сравнении. Выведите сводку по дням с числом разошедшихся кук и список этих кук с днем и обоими значениями счета. Общая сумма за день могла бы скрыть взаимную компенсацию ошибок разных кук. По списку видно, у кого искать причину. Расхождений будет всего несколько. Если их нет, мир прожил мало дней. Прогоните несколько дней через [даги модельного времени](../handbook/airflow-dags.md#даги-мира) и повторите сверку. ### Расследование Выберите одну разошедшуюся куку. Выведите ее события за два соседних дня с `UTCEventTime`, `EventDate`, `VisitID` и номером своей сессии. Сопоставьте сессии через события: общего ключа у двух нарезок нет, зато у каждого события есть и `VisitID`, и присвоенный вами номер. Найдите два соседних события, между которыми границы визитов разошлись. Запишите куку, день, время обоих событий и причину одним предложением. Уточните определение визита и добейтесь нуля расхождений во всех днях. ## Как проверить себя Сохраните исходный и уточненный расчеты, результаты сверки и найденные строки. Таблицы и представления создавать не нужно. Задачи в `homework_check` для этого задания нет: вы проверяете расчет своим запросом. В `sql/dds/session_rebuild.sql` и `sql/dq/sessions_vs_reference.sql` лежат готовые запросы нарезки и сверки. Откройте их после собственного решения и расследования. Сравните запросы со своими. Сопоставление со стендовой нарезкой по `session_id` остается на ступень 4. ## Что должно получиться - [ ] ваш запрос собирает сессии из всех событий `ods.event_v` за все доступные дни; - [ ] у вас есть сводка расхождений по дням и список кук, полученные через `FULL OUTER JOIN`; - [ ] вы объяснили причину одного расхождения и записали куку, день и два события, на которых оно видно; - [ ] уточненный расчет дает ноль расхождений во всех днях.