Группируйте просмотры страниц в сеансах, используя разницу времени - PullRequest
0 голосов
/ 05 июня 2018

У меня есть таблица с 3 полями: user_id, page и timestamp, которая выглядит примерно так:

user_id     page        timestamp
1234567     home.all    2018-03-01 00:10
7541231     task.now    2018-03-01 03:51
7541231     home.all    2018-03-01 03:53
4544731     talk.wow    2018-03-01 04:56
4544731     task.now    2018-03-01 05:01
4544731     home.all    2018-03-01 05:02
4544731     bla.home    2018-03-01 05:26
4544731     home.all    2018-03-01 06:40

Timestamp - это время, когда пользователь с данным ID загружает данную страницу на веб-сайте.Каждое наблюдение - это просмотр страницы.

Мне нужно назначить идентификатор сеанса для каждого наблюдения.Каждый идентификатор сеанса должен быть уникальным для каждого сеанса, где сеанс представляет собой группу просмотров страниц, где самые близкие друг к другу временные метки имеют разницу во времени не более чем 3600 секунд , полученную из same_id пользователя .

Результат должен выглядеть следующим образом:

user_id     page        timestamp           session_id
1234567     home.all    2018-03-01 00:10    1234567-2018030100100010
7541231     task.now    2018-03-01 03:51    7541231-2018030103510353
7541231     home.all    2018-03-01 03:53    7541231-2018030103510353
4544731     talk.wow    2018-03-01 04:56    4544731-2018030104560526
4544731     task.now    2018-03-01 05:01    4544731-2018030104560526
4544731     home.all    2018-03-01 05:02    4544731-2018030104560526
4544731     bla.home    2018-03-01 05:26    4544731-2018030104560526
4544731     home.all    2018-03-01 06:40    4544731-2018030106400640

Не могли бы вы, пожалуйста, предложить какой-либо запрос по этому поводу?

1 Ответ

0 голосов
/ 06 июня 2018

Если вы можете убедиться, что пара user_id и timestamp уникальна, вам может помочь следующее:

WITH cte AS
(
SELECT h1.user_id,
       h1.page,
       h1.timestamp,
       coalesce(h1.timestamp - h2.timestamp <= INTERVAL '3600 SECONDS', false) shares_session_with_previous,
       coalesce(h4.timestamp - h1.timestamp <= INTERVAL '3600 SECONDS', false) shares_session_with_next
       FROM hit h1
            LEFT JOIN hit h2
                      ON h2.user_id = h1.user_id
                         AND h2.timestamp = (SELECT max(h3.timestamp)
                                                    FROM hit h3
                                                    WHERE h3.user_id = h1.user_id
                                                          AND h3.timestamp < h1.timestamp)
            LEFT JOIN hit h4
                      ON h4.user_id = h1.user_id
                         AND h4.timestamp = (SELECT min(h5.timestamp)
                                                    FROM hit h5
                                                    WHERE h5.user_id = h1.user_id
                                                          AND h5.timestamp > h1.timestamp)
)
SELECT c1.user_id,
       c1.page,
       c1.timestamp,
       concat((SELECT concat(c2.user_id, '-', to_char(max(c2.timestamp), 'YYYYMMDDHH24MI'))
                      FROM cte c2
                      WHERE c2.user_id = c1.user_id
                            AND c2.timestamp <= c1.timestamp
                            AND NOT c2.shares_session_with_previous
                      GROUP BY c2.user_id),
              (SELECT to_char(min(c2.timestamp), 'HH24MI')
                      FROM cte c2
                      WHERE c2.user_id = c1.user_id
                            AND c2.timestamp >= c1.timestamp
                            AND NOT c2.shares_session_with_next)) session_id
       FROM cte c1
       ORDER BY c1.timestamp;

Основной частью является CTE.Для каждой строки присоединяется строка с самой младшей более старой отметкой времени и строка с самой старой младшей отметкой времени.Интервал между старшей или самой младшей отметкой времени и отметкой времени строки проверяется, чтобы быть меньше или равным 3600 секундам.Результат этих проверок сохраняется в флагах shares_session_with_previous и shares_session_with_next.

. Затем флаги используются для получения начала и конца сеанса.Начало - это самая младшая временная метка, которая старше или равна текущей временной метке, где shares_session_with_previous равно false.Конец - это самая старая отметка времени, которая меньше или равна текущей отметке времени, где shares_session_with_next равно false.

Соответствующие значения начала и конца сеанса объединяются для получения идентификатора сеанса.

SQL Fiddle

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...