我有一个由查询返回的表
+--------+------------------------+-------------------------+--------------+--------------+
| userid | logintime | logouttime | Download(KB) | Upload(KB) |
+--------+------------------------+-------------------------+--------------+--------------+
| ma29 | "2015-07-29 16:25:50" | "2015-07-29 16:38:17" | 86.6904 | 25.1328 |
| ma29 | "2015-07-29 16:38:47" | "2015-07-29 17:45:41" | 920.2256 | 16005.5889 |
| ma29 | "2015-07-29 17:47:32" | "2015-07-29 17:54:09" | 18.2939 | 10.9756 |
| ma29 | "2015-07-29 17:54:38" | "2015-07-29 17:56:31" | 0.0000 | 0.0000 |
| ma29 | "2015-07-29 17:56:39" | "2015-07-29 18:16:53" | 78.5596 | 57.5908 |
+--------+------------------------+-------------------------+--------------+--------------+
如何计算用户在给定时间范围内按小时计算的活动时间,如下所示:
例如:在2015-07-29 16:00到2015-07-30 11:00之间按小时搜索用户的活动时间:
+---------------+-------------------+
| Hours | Active Time(secs) |
+---------------+-------------------+
| 2015-07-29 16 | 2020 |
| 2015-07-29 17 | 3452 |
| 2015-07-29 18 | 1013 |
| ............. | ................. |
| ............. | ................. |
| ............. | ................. |
| ............. | ................. |
| 2015-07-30 09 | 0 |
| 2015-07-30 10 | 10 |
+---------------+-------------------+
我被困住了。不知道如何开始这个解决方案。另一个查询或存储过程??
答案 0 :(得分:1)
<强>计划强>
digits_v
以生成序列hours
数字,直到999(如果这小于输入之间的最大差异,那么只需用另一个交叉连接和10的幂来扩展)allhours
构建hours
,直到达到结束输入使用条件
将allhours
加入会话
date_add(allhours.hourstart, interval 1 hour) > s.logintime
and allhours.hourstart < s.logouttime
这将采用allhours
小时内有效的记录。
<强>查询强>
select hourstart, userid, sum(time_to_sec(timediff(clamp_right, clamp_left))) as active
from
(
select
allhours.hourstart,
s.userid,
s.logintime,
s.logouttime,
case when s.logintime is null or (s.logintime < allhours.hourstart)
then allhours.hourstart
else s.logintime
end as clamp_left
,
case when s.logouttime is null
then allhours.hourstart
when s.logouttime > date_add(allhours.hourstart, interval 1 HOUR)
then date_add(allhours.hourstart, interval 1 HOUR)
else s.logouttime
end as clamp_right
from
(
select date_add(str_to_date('2015-07-29 16:00', '%Y-%m-%d %H:%i'),
interval a2.n * 100 + a1.n * 10 + a0.n HOUR) as hourstart
from digits_v a2
cross join digits_v a1
cross join digits_v a0
) allhours
left join sessions s
on
(
date_add(allhours.hourstart, interval 1 hour) > s.logintime
and allhours.hourstart < s.logouttime
)
where hourstart < str_to_date('2015-07-30 11:00', '%Y-%m-%d %H:%i')
) q1
group by hourstart, userid
order by hourstart, userid
;
<强>输出强>
+------------------------+--------+--------+
| hourstart | userid | active |
+------------------------+--------+--------+
| July, 29 2015 16:00:00 | ma29 | 2020 |
| July, 29 2015 17:00:00 | ma29 | 3452 |
| July, 29 2015 18:00:00 | ma29 | 1013 |
| July, 29 2015 19:00:00 | (null) | 0 |
| July, 29 2015 20:00:00 | (null) | 0 |
| July, 29 2015 21:00:00 | (null) | 0 |
| July, 29 2015 22:00:00 | (null) | 0 |
| July, 29 2015 23:00:00 | (null) | 0 |
| July, 30 2015 00:00:00 | (null) | 0 |
| July, 30 2015 01:00:00 | (null) | 0 |
| July, 30 2015 02:00:00 | (null) | 0 |
| July, 30 2015 03:00:00 | (null) | 0 |
| July, 30 2015 04:00:00 | (null) | 0 |
| July, 30 2015 05:00:00 | (null) | 0 |
| July, 30 2015 06:00:00 | (null) | 0 |
| July, 30 2015 07:00:00 | (null) | 0 |
| July, 30 2015 08:00:00 | (null) | 0 |
| July, 30 2015 09:00:00 | (null) | 0 |
| July, 30 2015 10:00:00 | (null) | 0 |
+------------------------+--------+--------+
<强> sqlfiddle 强>