mysql数据库中有用户的玩游戏开始时间和结束时间,计算每个小时在玩游戏的人数,有跨小时、跨天的场景

假设用户的玩游戏的开始时间和结束时间分别存储在game表的start_time和end_time字段中,每个记录还有一个id字段表示用户ID,需要统计每个小时在玩游戏的人数,包括跨小时、跨天的情况。

可以使用MySQL的DATE_FORMAT函数提取小时部分,然后使用GROUP BY语句按小时分组,在每个小时内统计玩游戏的人数。

查询语句如下:

```

SELECT DATE_FORMAT(start_time, '%Y-%m-%d %H:00:00') AS hour_start,

COUNT(DISTINCT id) AS player_count

FROM game

GROUP BY hour_start;

```

这个查询语句将每个start_time转换为对应的小时开始时间,并统计每个小时内不同的id数(即玩游戏的人数)。结果类似这样:

```

+---------------------+-------------+

| hour_start | player_count|

+---------------------+-------------+

| 2022-01-01 00:00:00 | 10 |

| 2022-01-01 01:00:00 | 8 |

| 2022-01-01 02:00:00 | 12 |

| ... | ... |

```

这个查询语句可以应对大多数情况,但是有一种特殊情况需要注意:如果一个游戏开始时间跨越多个小时,那么它会被统计多次,而同一个用户可能会在不同的小时内都被统计。如果需要避免这种情况,可以使用时间序列表生成需要统计的小时,然后LEFT JOIN游戏表,只统计每个小时内的不同id数。

以下是示例代码:

```

CREATE TABLE hours (hour_start DATETIME);

INSERT INTO hours (hour_start)

SELECT CONCAT(DATE_FORMAT(start_time, '%Y-%m-%d %H'), ':00:00') AS hour_start

FROM (

SELECT MIN(start_time) AS min_start, MAX(end_time) AS max_end

FROM game

) AS time_range

JOIN (

SELECT @row := @row + INTERVAL 1 HOUR AS hour

FROM information_schema.columns, (SELECT @row := time_range.min_start - INTERVAL 1 HOUR FROM (SELECT 1) AS init) AS vars

WHERE @row <= time_range.max_end

AND DATE_FORMAT(@row, '%i') = '00'

) AS time_seq

ON 1=1;

SELECT hours.hour_start,

COUNT(DISTINCT game.id) AS player_count

FROM hours

LEFT JOIN game

ON game.start_time <= hours.hour_start + INTERVAL 1 HOUR

AND game.end_time >= hours.hour_start

GROUP BY hours.hour_start;

```

这个查询语句使用了一个名为hours的时间序列表,它包含了需要统计的每个小时。首先查询game表中的最早开始时间和最晚结束时间,然后使用information_schema.columns生成时间序列,从最早开始时间的前一小时开始,每隔1小时生成一个时间,直到最晚结束时间为止。需要注意的是,如果不使用DATE_FORMAT函数将分钟部分设为0,时间序列会包含每个小时的60分钟,这会导致统计错误。

然后将时间序列表和game表LEFT JOIN,只统计在每个小时内在玩游戏的用户数。LEFT JOIN可以保证每个小时都被统计到,即使这个小时内没有用户在玩游戏。结果类似这样:

```

+---------------------+-------------+

| hour_start | player_count|

+---------------------+-------------+

| 2022-01-01 00:00:00 | 10 |

| 2022-01-01 01:00:00 | 8 |

| 2022-01-01 02:00:00 | 12 |

| ... | ... |

```

这个查询语句比第一个查询语句稍微复杂一点,但是可以应对跨小时、跨天的情况,统计的结果更加准确。 ♨

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值