MySQL计算日志文件成对时差之和
我在mysql中有一个记录用户操作的表。表中的每一行对应一个用户操作,如登录、注销等 该表如下所示:MySQL计算日志文件成对时差之和,mysql,date,datediff,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
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为6的用户在特定日期范围内登录的总时间(小时:分钟:秒)
我的第一个想法是使用操作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
从用户活动日志中选择TIMEDIFF(ual1.action\u已创建,ual2.action\u已创建)
ual1,用户活动日志ual2,其中ual1.user\u id=6和ual2.user\u id=6和
ual1.action_type=1和ual2.action_type=2,以及
日期(ual1.action_created)=“2013-07-21”和
DATE(ual1.action_created)我认为构造此类查询的最简单方法是使用相关子查询(老实说,我通常不喜欢相关子查询,但这是一个例外)。您的查询可能会使用右侧的GROUPBY
子句
以下是另一种方法:
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))