我有用户connection/disconnection
日志表:
id user_id timestamp action
1 8 2017-05-01 10:25 connect
2 8 2017-05-01 11:00 disconnect
3 8 2017-05-01 12:10 connect
3 15 2017-05-01 12:11 connect
3 8 2017-05-01 12:10 disconnect
我的问题是我可以选择user_id:8个活动时间,以小时为单位,例如: 2017-05-01
吗
我尝试从connections
时间较大的用户和left join
用户中选择disconnect
,然后连接时间并保留第一行
SELECT u.*,u2.* FROM `user_log` as u
INNER JOIN `user_log` as u2 ON u2.action = 'disconnect'
AND u.user_id = u2.user_id AND u.`timestamp` < u2.`timestamp`
WHERE u.action = 'connect'
GROUP BY u.id
似乎它正常工作,但我不确定它是否是最好的方法,也有用户连接05-01
但未连接05-02
时未涵盖的情况,因此这意味着我必须计算到05-01
中午12点
答案 0 :(得分:1)
我认为您可以使用此查询:
select `user_id`, `date`
, sum(timestampdiff(minute,`connectTime`,`disconnectTime`)) `totalMinutes`
from (
select `l`.`id`, `l`.`user_id`, date(`l`.`timestamp`) as `date` , `l`.`timestamp` as `connectTime`, `l`.`action`
, coalesce(
/* finding first row of disconnect logs after this connect log */
(select `li`.`timestamp`
from `logs` as `li`
where `l`.`user_id`= `li`.`user_id` /* user_id should be same */
and `l`.`timestamp` < `li`.`timestamp` /* disconnect time should be bigger than connect time */
and `li`.`action` = 'disconnect'
order by `l`.`timestamp`
limit 1),
date_add(date_add(date(`l`.`timestamp`), interval 1 day), interval -1 minute) /* calculate last minute of current date */
) as `disconnectTime`
from `logs` as `l`
/* filter connect logs only */
where `l`.`action` = 'connect') `t`
group by `user_id`, `date`;
答案 1 :(得分:0)
select con.user_id,SEC_TO_TIME(sum(TIME_TO_SEC(timediff(dis.timestamp,con.timestamp))))timeinuse
from(SELECT @a :=@a+1 as line,w.user_id,w.id,w.timestamp ,w.action
from user_log w ,(select @a:= 0)l
where w.action = 'connect' order by w.user_id,w.timestamp)con inner join
(SELECT @b:=@b+1 as line ,w.timestamp,w.user_id
from user_log w ,(select @b:= 0)l where w.action = 'disconnect' group by w.id,w.user_id
order by w.user_id,w.timestamp)dis on con.line = dis.line and con.user_id =dis.user_id group by con.user_id;
答案 2 :(得分:0)
在@ shA.t和其他人的帮助下评论海报
我终于找到了这个问题的答案!
SELECT *, sum(timestampdiff(minute,`connect_timestamp`,`disconnect_timestamp`)) `totalMinutes`
FROM (
SELECT user_id, LEAST(start_date, second_date) AS connect_timestamp, GREATEST(start_date, second_date) AS disconnect_timestamp
FROM (
SELECT l.id, l.user_id,`l`.`timestamp` AS start_date,
(CASE
WHEN l.action = 'connect' THEN (
coalesce(
(select `li`.`timestamp`
from `logs` as `li`
where `l`.`user_id`= `li`.`user_id`
and `l`.`timestamp` < `li`.`timestamp`
and DATE(`l`.`timestamp`) = DATE(`li`.`timestamp`)
and `li`.`action` = 'disconnect'
order by `l`.`timestamp`
limit 1),
date_add(date_add(date(`l`.`timestamp`), interval 1 day), interval -1 minute)
)
)
WHEN l.action = 'disconnect' THEN (
coalesce(
(select `li`.`timestamp`
from `logs` as `li`
where `l`.`user_id`= `li`.`user_id`
and `l`.`timestamp` > `li`.`timestamp`
and DATE(`l`.`timestamp`) = DATE(`li`.`timestamp`)
and `li`.`action` = 'connect'
order by `l`.`timestamp`
limit 1),
date_add(date(`l`.`timestamp`), interval 0 minute)
)
)
END) as second_date
FROM `logs` as `l`
) as t GROUP BY connect_timestamp
) as t2 GROUP BY user_id, DATE(connect_timestamp)