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