MySQL计算日志文件成对时差的总和

时间:2013-07-21 13:25:56

标签: mysql date datediff

我在mysql中有一个表来记录用户操作。表中的每一行都对应一个用户操作,如登录,注销等。

表格如下:

CREATE TABLE IF NOT EXISTS `user_activity_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`action_type` smallint NOT NULL,
`action_created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_bin;


id  user_id  action_type    action_created
...
22    6        1        2013-07-21 14:31:14
23    6        2        2013-07-21 14:31:16
24    8        2        2013-07-21 14:31:18
25    8        1        2013-07-21 14:45:18
26    8        0        2013-07-21 14:45:25
27    8        1        2013-07-21 14:54:54
28    8        2        2013-07-21 15:09:11
29    6        1        2013-07-21 15:09:17
30    6        2        2013-07-21 15:09:29
...

想象一下操作1是登录 2是注销,我想找出用户的总时间(小时:分钟:秒)在特定日期范围内登录了ID为的文件。

我的第一个想法是使用操作1或2获取所有行,并自己计算PHP中的日期差异。这看起来相当复杂,我相信这也可以在mysql的一个查询中完成!

我试过的是:

SELECT TIMEDIFF(ual1.action_created, ual2.action_created) FROM user_activity_log
ual1,user_activity_log ual2  WHERE ual1.user_id = 6 AND ual2.user_id = 6 AND
ual1.action_type = 1 AND ual2.action_type = 2 AND
DATE(ual1.action_created) >= '2013-07-21' AND
DATE(ual1.action_created) <= '2013-07-21'
ORDER BY ual1.action_created

从ual1中选择所有登录事件,从同一用户选择ual2的所有登出事件,然后计算2013.7.21日的成对时差,这实际上并不起作用,我不知道原因。

如何计算总登录时间(所有时差的总和,日期操作2 - 日期操作1 )? 正确操作的结果应该是 2秒来自log id对22,23 + 12秒来自log id对29,30 = 14秒

非常感谢您的帮助。最好的问候

1 个答案:

答案 0 :(得分:1)

我认为构建此类查询的最简单方法是使用相关子查询(说实话,我通常不喜欢相关子查询,但这是一个例外)。您的查询可能适用于正确的group by子句。

这是另一种方法:

select TIMEDIFF(action_created, LogoutTS)
from (select ual.*,
             (select ual2.user_activity_log
              from user_activity_log ual2
              where ual2.user_id = ual.user_id and
                    ual2.action_type = 2 and
                    ual2.action_created > ual.action_created
              order by ual2.action_created desc
              limit 1
             ) as LogoutTS
      from user_activity_log ual
      where ual.user_id = 6 and
            ual.action_type = 1
     ) ual

要获得总数,您需要执行sum(TIMEDIFF(action_created, LogoutTS)之类的操作。但是,这可能取决于时间列的格式。它可能看起来像这样:

select SUM((UNIX_TIMESTAMP(LogoutTS) - UNIX_TIMESTAMP(action_created))/1000)

或者:

select sec_to_time(SUM((UNIX_TIMESTAMP(LogoutTS) - UNIX_TIMESTAMP(action_created))/1000))