【问题标题】:Is it possible to get active sessions per hour in SQL?是否可以在 SQL 中每小时获得活动会话?
【发布时间】:2021-08-30 15:42:53
【问题描述】:
start_time end_time HostID gameID
6/14/2021 20:13 6/14/2021 22:22 1 AB1
6/14/2021 20:20 6/14/2021 21:47 2 AB2
6/14/2021 20:22 6/14/2021 22:07 3 AB3
6/14/2021 20:59 6/14/2021 21:15 4 AB4
6/15/2021 21:24 6/15/2021 22:09 1 AB5
6/15/2021 21:24 6/15/2021 21:59 2 AB6
6/15/2021 23:11 6/16/2021 01:22 4 AB7
6/16/2021 20:13 6/16/2021 21:23 3 AB8

我有一张有开始时间和结束时间的表格。我想计算每小时活跃的游戏室。我知道我至少应该尝试解决这个问题,但我真的不知道从哪里开始,也不知道这是否可以使用 SQL。

我首先做的是使用 start_time 计算一个小时内有多少个游戏 ID。但我确定我没有回答每个会话的“活跃”问题。我所做的只是统计每小时有多少人开始玩游戏。

预期的结果是这样的

白天

Time Active
6/14/2021 2000 4
6/15/2021 2100 4
6/16/2021 2200 2
6/15/2021 2100 2
6/16/2021 2200 1
6/17/2021 2300 1
6/16/2021 0 1
6/17/2021 1 1
6/18/2021 2000 1
6/19/2021 2100 1

或不按天分组的每小时活跃会话数。

小时

Time Active
2000 5
2100 7
2200 3
2300 1
0000 1
0001 1

【问题讨论】:

    标签: sql google-bigquery data-analysis


    【解决方案1】:

    一个简单的方法是取消透视数据然后聚合。要随时获取数据中的数字:

    with se as (
          select start_time as time, 1 as inc from t
          union all
          select end_time, -1 as inc from t
         )
    select time, sum(sum(inc)) over (order by time) as actives
    from se
    group by time;
    

    然后,您需要定义“每小时”的含义。您可以使用trunc() 获得每小时的第一个结果:

    with se as (
          select start_time as time, 1 as inc from t
          union all
          select end_time, -1 as inc from t
         )
    select time, sum(sum(inc)) over (order by time) as actives
    from se
    group by time
    qualify row_number() over (partition by date_trunc(time, hour) order by time) = 1;
    

    【讨论】:

      【解决方案2】:

      我建议以下解决方案

      select timestamp_trunc(minute, hour) hour, 
        count(distinct hostid) hosts,
        count(distinct gameid) games
      from `project.dataset.table`, 
      unnest(generate_timestamp_array(
        parse_timestamp('%m/%d/%Y %H:%M', start_time), 
        parse_timestamp('%m/%d/%Y %H:%M', end_time), 
        interval 1 minute)) minute
      group by hour
      # order by hour          
      

      如果应用于您问题中的样本数据(最后一行的 end_time 修复 - 应该是 6/16/2021 21:23 - 不是 6/6/2021 21:23) - 输出是

      简要说明

      1. start_timeend_time 之间每分钟将每个原始行扩展/拆分为一行
      2. 然后,通过hour 应用count(distinct ...) 进行简单聚合

      或不按天分组的每小时活跃会话数。

      你可以应用完全相同的方法

      select extract(hour from minute) hour, 
        count(distinct hostid) hosts,
        count(distinct gameid) games
      from `project.dataset.table`, 
      unnest(generate_timestamp_array(
        parse_timestamp('%m/%d/%Y %H:%M', start_time), 
        parse_timestamp('%m/%d/%Y %H:%M', end_time), 
        interval 1 minute)) minute
      group by hour
      order by hour             
      

      有输出

      【讨论】:

      • 那么,你试过了吗?以上对你有用吗?!
      • 鉴于您包含的快照,它应该但我仍在试图弄清楚如何使用 parse_timestamp 来使用这种格式的数据时间表达式:2021-10-11T16:06:43。另外,为什么我们以每分钟间隔而不是每小时间隔来做呢?我们是否在 FROM 语句中执行交叉连接?是这样吗?
      • 正确!我们拆分几分钟,然后聚合(分组)小时 - 这是为了解决开始和结束时间不同的情况。从时间戳到日期时间 - 只需使用 datetime() 函数。我认为您的问题已得到充分回答。所以,如果还没有投票,请考虑投票并接受答案:o)
      • 有效的是 timestamp() 函数。谢谢,
      猜你喜欢
      • 1970-01-01
      • 2016-11-30
      • 2012-01-25
      • 2015-06-08
      • 2012-03-06
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 2015-12-23
      相关资源
      最近更新 更多