Вывести продолжительность сеанса, когда в SQL доступна только временная метка - PullRequest
0 голосов
/ 18 октября 2018

Я хочу рассчитать продолжительность сеанса для использования приложения.Однако в предоставленном журнале единственная соответствующая информация, которую я могу получить, - это отметка времени.Ниже приведен упрощенный журнал для одного пользователя.

record_num, user_id, record_ts
-----------------------------
1, uid_1, 12:01am
2, uid_1, 12:02am
3, uid_1, 12:03am
4, uid_1, 12:22am
5, uid_1, 12:22am
6, uid_1, 12:25am

Если сеанс завершен после 15 минут бездействия, указанный журнал будет состоять из 2 сеансов.А теперь я хотел бы рассчитать среднюю продолжительность для двух сессий.

Я могу определить количество сессий, сначала рассчитав разницу во времени между каждой записью, и всякий раз, когда разница превышает 15 минут, подсчитывается сессия.

Но чтобы вывести длительность, мне нужно знать min (record_ts) и max (record_ts) для каждой сессии.Однако без какого-либо идентификатора сеанса я не смог бы сгруппировать записи в связанные сеансы.

Существует ли какой-либо подход на основе SQL, в котором я могу решить эту проблему?

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Я бы сделал это в следующих шагах:

  • Используйте lag() и некоторую логику, чтобы определить, когда начинается сеанс.
  • Используйте совокупную сумму для назначения сеансов.
  • Затем агрегирование для получения средних значений.

Итак, для получения информации о каждом сеансе:

select user_id, session, min(record_ts), max(record_ts),
       timestamp_diff(max(record_ts), min(record_ts), second) as dur_seconds
from (select l.*,
             countif( record_ts > timestamp_add(prev_record_ts, interval 15 minute) ) as session
      from (select l.*,
                   lag(record_ts, 1, record_ts) over (partition by user_id order by record_ts) as prev_record_ts
            from log l
           ) l
group by record_num, user_id;

Среднее значение - это еще один шаг:

with s as (
      select user_id, session, min(record_ts), max(record_ts),
             timestamp_diff(max(record_ts), min(record_ts), second) as dur_seconds
      from (select l.*,
                   countif( record_ts > timestamp_add(prev_record_ts, interval 15 minute) ) as session
            from (select l.*,
                         lag(record_ts, 1, record_ts) over (partition by user_id order by record_ts) as prev_record_ts
                  from log l
                 ) l
      group by record_num, user_id
     )
select user_id, avg(dur_seconds)
from s
group b user_id;
0 голосов
/ 18 октября 2018

Предполагая, что у вас тоже есть дата (без нее будет означать вычисление того, началось ли время окончания сеанса раньше времени начала), будет работать что-то вроде этого:

WITH CTE AS
(SELECT * FROM
(SELECT 1 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:01:00') record_ts)
UNION ALL
(SELECT 2 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:02:00') record_ts)
UNION ALL
(SELECT 3 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:03:00') record_ts)
UNION ALL
(SELECT 4 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:22:00') record_ts)
UNION ALL
(SELECT 5 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:22:00') record_ts)
UNION ALL
(SELECT 6 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:25:00') record_ts)
UNION ALL
(SELECT 7 record_num, "uid_1" user_id, TIMESTAMP('2018-10-01 12:59:00') record_ts)),

sessions as
(SELECT
  if(timestamp_diff(record_ts,lag(record_ts,1) OVER (PARTITION BY user_id ORDER BY     
    record_ts, record_num),MINUTE) >= 15 OR
    lag(record_ts,1) OVER (PARTITION BY user_id ORDER BY record_ts, record_num) IS NULL,1,0)
  session, record_num, user_id, record_ts
FROM CTE)

SELECT sum(session) OVER (PARTITION BY user_id ORDER BY record_ts, record_num) 
  sessionNo, record_num, user_id, record_ts
FROM sessions 

Ключом является числоминуты вы хотите между сессиями.В приведенном выше случае я поставил его на 15 минут (> = 15).Очевидно, что было бы полезно объединить номер сеанса с user_Id и временем начала сеанса, чтобы создать уникальный идентификатор сеанса.

enter image description here

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