2017-10-08 116 views
0

我有一个包含时间戳登录的表的MySQL数据库,我想获得过去24小时每个小时的登录次数。显示每小时的汇总数据

起初,我尝试了一些东西明显:

SELECT 
    timestamp AS Hour, 
    COUNT(*) AS Logins 
FROM auth 
WHERE 
    timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY) 
GROUP BY HOUR(timestamp) 
ORDER BY timestamp DESC 

这导致类似以下的输出:

+---------------------+--------+ 
| Hour    | Logins | 
+---------------------+--------+ 
| 2017-10-08 17:00:05 | 272 | 
| 2017-10-08 16:00:02 | 323 | 
| 2017-10-08 15:00:34 | 301 | 
| 2017-10-08 14:55:10 |  30 | 
| 2017-10-08 11:04:27 | 107 | 
| 2017-10-08 10:06:26 | 115 | 
| 2017-10-08 09:00:11 |  92 | 
| 2017-10-08 08:02:34 | 195 | 
| 2017-10-08 07:03:15 | 171 | 
| 2017-10-08 06:03:06 | 133 | 
| 2017-10-08 05:00:20 | 102 | 
| 2017-10-08 04:03:23 | 198 | 
| 2017-10-08 03:00:23 | 345 | 
| 2017-10-08 02:01:39 | 318 | 
| 2017-10-08 01:01:22 | 205 | 
| 2017-10-08 00:00:24 | 334 | 
| 2017-10-07 23:00:00 | 501 | 
| 2017-10-07 22:00:10 | 377 | 
| 2017-10-07 21:00:02 | 482 | 
| 2017-10-07 20:00:04 | 349 | 
| 2017-10-07 19:00:54 | 298 | 
| 2017-10-07 18:13:06 | 438 | 
+---------------------+--------+ 
22 rows in set (0,02 sec) 

有两个问题与此输出。第一个是时间戳不是在整个小时,因为第一次登录发生在确切的小时后几分钟/秒。另外,我并不需要输出中的日期。我已经做了以下的解决了这个问题:

SELECT 
    DATE_FORMAT(DATE_ADD(timestamp, INTERVAL 30 MINUTE),'%H:00:00') AS Hour, 
    COUNT(*) AS Logins 
FROM auth 
WHERE 
    timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY) 
GROUP BY HOUR(timestamp) 
ORDER BY timestamp DESC 

现在的产量是

+----------+--------+ 
| Hour  | Logins | 
+----------+--------+ 
| 17:00:00 | 272 | 
| 16:00:00 | 323 | 
| 15:00:00 | 301 | 
| 15:00:00 |  30 | 
| 11:00:00 | 107 | 
| 10:00:00 | 115 | 
| 09:00:00 |  92 | 
| 08:00:00 | 195 | 
| 07:00:00 | 171 | 
| 06:00:00 | 133 | 
| 05:00:00 | 102 | 
| 04:00:00 | 198 | 
| 03:00:00 | 345 | 
| 02:00:00 | 318 | 
| 01:00:00 | 205 | 
| 00:00:00 | 334 | 
| 23:00:00 | 501 | 
| 22:00:00 | 377 | 
| 21:00:00 | 482 | 
| 20:00:00 | 349 | 
| 19:00:00 | 298 | 
| 18:00:00 | 452 | 
+----------+--------+ 
22 rows in set (0,00 sec) 

问题1:这是这样做的(显示整个小时)的一个很好的方式或有更好的吗?

第二个问题我不知道如何解决。你看,上述命令在当地时间18点19分执行。请注意,18:00到18:19之间登录的次数不足。是的,我知道最后一整小时还没有结束,但我仍然想要显示已经过去的那部分数据。

问题2:如何做到这一点?

+0

我倾向于认为它是不好的做法,除了你选择的东西以外的其他任何东西。显示问题应该在应用代码 – Strawberry

+0

@Strawberry中处理,不确定你的意思。我选择并按'timestamp'分组。你的意思是我应该用'HOUR(DATE_ADD(timestamp,INTERVAL 30 MINUTE))'而不是'DATE_FORMAT(DATE_ADD(时间戳,INTERVAL 30 MINUTE),'%H:00:00')'?好吧,无论如何,但是问题2并没有解决这个问题。 – bontchev

+0

你为什么要在30分钟内添加''timestamp''? – kmoser

回答

0

由于@kmoser指出,问题就来了一个事实,即在24小时内的最后一个(不完全)小时将数据分组与它的第一个小时 - 因为小时数是相同。为了解决这个问题,我们需要根据区分不同日子的相同时间来区分。这里是适用于我的解决方案:

SELECT 
    DATE_FORMAT(timestamp, '%Y-%m-%d %H:00:00') AS Hour, 
    COUNT(*) AS Logins 
FROM auth 
WHERE 
    timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY) 
GROUP BY DATE_FORMAT(timestamp, '%Y-%m-%d %H:00:00') 
ORDER BY timestamp DESC 
0
select count(*) as cnt 
from auth 
where date >= DATE_SUB(NOW(),INTERVAL 1 HOUR); 
+0

这个答案是可怕的,完全错误的。你甚至理解这个问题吗? – bontchev