преобразование журналов в среднее количество пользователей в день - PullRequest
1 голос
/ 27 июня 2019

Я пытаюсь преобразовать журналы в среднее количество сеансов в день недели или в час.

У меня есть таблица, похожая на

user_id | session_id | session_start_time | fleet_name

и я хочу, чтобы таблица выглядела следующим образом

флот | день недели / час | avg (count (session_id)

Я используюbigquery o сделать это, чтобы отправить данные в datastudio. Целью было бы показать количество соединений в среднем по данному флоту в понедельник или в 8 часов утра

SELECT fleet_name,extract(dayofweek from date) as day, avg(count_user) 
FROM( SELECT extract(date from session_start_time) as date,
          COUNT(user_id)as count_user,fleet_name
      FROM `gbl-ist-ve-aws-appstream-costs.appstream_dataset.log_sessions`
      group by date,fleet_name)
group by fleet_name, day

проблема, с которой я столкнулсяКод ниже состоит в том, что он игнорирует день / час, когда никто не соединяется, поэтому среднее значение неверно. Я видел некоторые ответы по аналогичной проблеме с внутренним объединением, но у меня нет другой таблицы с днем ​​/ часом для каждого парка, если ясоздать один. Я также думал о делении общего количества на количество дней недели или часов (количество дней в году) между двумя датами, но это может быть извращенным способом продолжить ...

Любая помощь будет ценной

Ответы [ 2 ]

1 голос
/ 27 июня 2019

Если я правильно понимаю вашу проблему, если в течение 5 последовательных понедельников (например), вы видите число пользователей 10, 10, 0, 10, 10. Вы ожидаете, что среднее значение будет 8, но ваша внутренняя подгруппазапрос возвращает только 4 десятка, а вы видите в среднем 10?

Чтобы решить эту проблему, я бы сгенерировал массив дат и оставил присоединить ваши данные к этому.Это гарантирует, что каждая дата имеет счетчик, даже если он равен 0. Затем вам нужно будет включить 0 в ваше среднее значение.

with calendar as (
  SELECT date 
  FROM UNNEST( GENERATE_DATE_ARRAY(DATE('2019-06-01'), CURRENT_DATE(), INTERVAL 1 DAY) ) AS date
),
daily_counts as (
  SELECT 
    fleet_name, 
    extract(date from session_start_time) as date,
    COUNT(user_id)as count_user
  FROM <table>
  group by 1,2
)
select
  fleet_name,
  date,
  avg( ifnull(count_user,0) ) as avg_daily_user_count
from calendar
left join daily_counts using(date)
group by 1,2
0 голосов
/ 27 июня 2019

Я также думал о том, чтобы разделить общее количество на число дней недели или часов (количество дней в году) между двумя датами, но это может быть неправильным способом ...

Я думаю, что это может быть хорошей идеей!
Ниже приведен пример для иллюстрации

#standardSQL
SELECT fleet_name, EXTRACT(dayofweek FROM DATE) AS day, 
  SUM(count_user) / (DATE_DIFF(MAX(DATE), MIN(DATE), WEEK) + 1)
FROM( SELECT EXTRACT(DATE FROM session_start_time) AS DATE,
          COUNT(user_id) AS count_user,fleet_name
      FROM `gbl-ist-ve-aws-appstream-costs.appstream_dataset.log_sessions`
      GROUP BY DATE,fleet_name)
GROUP BY fleet_name, day  

Взгляните на SUM(count_user) / (DATE_DIFF(MAX(DATE), MIN(DATE), WEEK) + 1) - это замена avg(count_user).Я быстро проверил фиктивные данные и, похоже, работает

Как видите, я предполагаю, что ваш запрос концептуально корректен, поэтому я не изменяю ничего другого

...