是否有可能在 SQL 中获得每小时的活动会话数?
Is it possible to get active sessions per hour in SQL?
start_time
end_time
主机ID
游戏ID
2021/6/1420:13
2021/6/1422:22
1
AB1
2021/6/1420:20
2021 年 6 月 14 日 21:47
2
AB2
2021/6/1420:22
2021/6/1422:07
3
AB3
2021 年 6 月 14 日 20:59
2021/6/1421:15
4
AB4
2021 年 6 月 15 日 21:24
2021 年 6 月 15 日 22:09
1
AB5
2021 年 6 月 15 日 21:24
2021/6/1521:59
2
AB6
2021 年 6 月 15 日 23:11
2021 年 6 月 16 日 01:22
4
AB7
2021 年 6 月 16 日 20:13
2021 年 6 月 16 日 21:23
3
AB8
我有一个 table 有开始时间和结束时间。我想计算每小时活跃的游戏室。我知道我至少应该尝试解决这个问题,但我真的不知道从哪里开始,或者这是否可能 SQL.
我首先做的是使用 start_time 计算一个小时内有多少个 gameID。但我确定我没有回答 'active' per session 问题。我所做的只是计算每小时有多少人开始玩游戏。
预期的结果是这样的
工作日
时间
有效
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
2021 年 6 月 16 日 0
1
2021 年 6 月 17 日 1
1
6/18/2021 2000
1
6/19/2021 2100
1
或者不按天分组的每小时活动会话数。
小时
时间
有效
2000
5
2100
7
2200
3
2300
1
0000
1
0001
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;
我建议以下解决方案
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 ) - 输出是
简要说明
- Expand/split 每个原始行在
start_time
和 end_time
之间每分钟变成一行
- 然后,简单地通过
hour
应用 count(distinct ...)
进行聚合
Or count of active sessions per hour without grouping by day.
您可以应用完全相同的方法
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
有输出
start_time | end_time | 主机ID | 游戏ID |
---|---|---|---|
2021/6/1420:13 | 2021/6/1422:22 | 1 | AB1 |
2021/6/1420:20 | 2021 年 6 月 14 日 21:47 | 2 | AB2 |
2021/6/1420:22 | 2021/6/1422:07 | 3 | AB3 |
2021 年 6 月 14 日 20:59 | 2021/6/1421:15 | 4 | AB4 |
2021 年 6 月 15 日 21:24 | 2021 年 6 月 15 日 22:09 | 1 | AB5 |
2021 年 6 月 15 日 21:24 | 2021/6/1521:59 | 2 | AB6 |
2021 年 6 月 15 日 23:11 | 2021 年 6 月 16 日 01:22 | 4 | AB7 |
2021 年 6 月 16 日 20:13 | 2021 年 6 月 16 日 21:23 | 3 | AB8 |
我有一个 table 有开始时间和结束时间。我想计算每小时活跃的游戏室。我知道我至少应该尝试解决这个问题,但我真的不知道从哪里开始,或者这是否可能 SQL.
我首先做的是使用 start_time 计算一个小时内有多少个 gameID。但我确定我没有回答 'active' per session 问题。我所做的只是计算每小时有多少人开始玩游戏。
预期的结果是这样的
工作日
时间 | 有效 |
---|---|
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 |
2021 年 6 月 16 日 0 | 1 |
2021 年 6 月 17 日 1 | 1 |
6/18/2021 2000 | 1 |
6/19/2021 2100 | 1 |
或者不按天分组的每小时活动会话数。
小时
时间 | 有效 |
---|---|
2000 | 5 |
2100 | 7 |
2200 | 3 |
2300 | 1 |
0000 | 1 |
0001 | 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;
我建议以下解决方案
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 ) - 输出是
简要说明
- Expand/split 每个原始行在
start_time
和end_time
之间每分钟变成一行
- 然后,简单地通过
hour
应用count(distinct ...)
进行聚合
Or count of active sessions per hour without grouping by day.
您可以应用完全相同的方法
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
有输出