我正在记录我社区中游戏玩家的统计数据.对于他们在线和游戏中的状态,我在他们"开始"和"结束"时注册.为了显示当天最活跃的日期和小时,我想使用一个SQL语句,根据"开始"和"结束"日期时间值来衡量最活跃的时刻.
查看SQL - 从db中选择大多数"活动"时间我可以看到相似之处,但我还需要包括开始和结束时间之间的时刻.
也许最简单的方法是编写一个执行计算的cron,但我希望这个问题可能会教我如何在SQL中解决这个问题.
我一直在搜索一个SQL语句,它允许创建一个日期时间段并使用它来减去单个小时和几天.但无济于事.
---更新
我正在考虑更多这方面,我想知道根据一天中的每个小时(最活跃的小时)运行24个查询以及最活跃的一天的几个查询是否明智.但这似乎是对性能的浪费.但是这个解决方案可能会使查询成为可能:
SELECT COUNT(`userID`), DATE_FORMAT("%H",started) AS starthour,
DATE_FORMAT("%H",ended) AS endhour
FROM gameactivity
WHERE starthour >= $hour
AND endhour <= $hour GROUP BY `userID`
Run Code Online (Sandbox Code Playgroud)
(为了示例的目的,添加了$小时,当然我正在使用PDO.列也仅用于示例目的,无论您认为哪些都很容易用于解释,可以识别为开始和结束对我来说是好的)
附加信息; PHP 5.5 +,PDO,MySQL 5+ ingame的表格布局将是:gameactivity:activityid,userid,gameid,started,ended
DDL:
CREATE TABLE IF NOT EXISTS `steamonlineactivity` (
`activityID` int(13) NOT NULL AUTO_INCREMENT,
`userID` varchar(255) NOT NULL,
`online` datetime DEFAULT NULL,
`offline` datetime DEFAULT NULL,
PRIMARY KEY (`activityID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;
Run Code Online (Sandbox Code Playgroud)
如果我正确理解您的要求,如果该图代表用户活动:
Day
12/1 12/2 12/3 12/4 ...
Hour 0 xx x x xx
1 x xx xx
2 xxx x x xx
3 x x
4 x x
5 x x
6 x
...
Run Code Online (Sandbox Code Playgroud)
您想知道 02:00 是一天中平均活动最高的时间(一行为 7 x),而 12/4 是最活跃的一天(一列为 10 x)。请注意,这并不意味着 12/4 的 02:00 是有史以来最活跃的时间,正如您在示例中看到的那样。如果这不是您想要的,请用输入和期望结果的具体示例进行澄清。
我们做出几个假设:
2013-12-02 23:35、线下2013-12-03 00:13。我们需要定义“活动”的含义。我选择了在每种情况下更容易计算的标准。如果需要,两者都可以变得更准确,但代价是查询更复杂。
对于一天中最活跃的时间,我们将使用一个小型辅助表来保存 24 小时的数据。它还可以使用其他答案中描述的技术动态生成和连接。
CREATE TABLE hour ( hour tinyint not null, primary key(hour) );
INSERT hour (hour)
VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
, (11), (12), (13), (14), (15), (16), (17), (18), (19), (20)
, (21), (22), (23);
Run Code Online (Sandbox Code Playgroud)
然后以下查询给出所需的结果:
SELECT hour, count(*) AS activity
FROM steamonlineactivity, hour
WHERE ( hour BETWEEN hour(online) AND hour(offline)
OR hour(online) BETWEEN hour(offline) AND hour
OR hour(offline) BETWEEN hour AND hour(online) )
GROUP BY hour
ORDER BY activity DESC;
SELECT date, count(DISTINCT userID) AS activity
FROM (
SELECT userID, date(online) AS date
FROM steamonlineactivity
UNION
SELECT userID, date(offline) AS date
FROM steamonlineactivity
) AS x
GROUP BY date
ORDER BY activity DESC;
Run Code Online (Sandbox Code Playgroud)