将日志转换为每天的平均用户数

时间:2019-06-26 22:59:35

标签: sql logging group-by google-bigquery average

我正在尝试将日志转换为每周或每小时的平均会话次数

我的桌子看起来像

  

user_id | session_id | session_start_time | fleet_name

我想有一张像这样的桌子

  

车队|工作日/小时|平均(计数(session_id)

我正在使用bigquery来将数据推送到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 个答案:

答案 0 :(得分:1)

如果我正确理解了您的问题,例如,如果连续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

答案 1 :(得分:0)

  

我也正在考虑将两个工作日之间的每个工作日或小时数(星期一)的总数除以,但这可能是一种扭曲的方式...

我认为这实际上是一个好主意!
以下是说明

的示例
#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)的替代品。我对伪数据进行了快速测试,并向我证明它有效

如您所见,我认为您的查询在概念上是正确的,因此,我没有做任何其他更改