我有一个这种格式的表:
id, user, action, date
1, user1, a1, 2013-03-20 10:00:01
2, user2, a1, 2013-03-20 10:00:03
3, user2, a1, 2013-03-20 10:00:12
4, user3, a1, 2013-03-20 10:00:20
5, user2, a1, 2013-03-20 10:00:24
....
...
继续使用30个不同用户的所有分钟和小时(24x7)...
现在我需要知道“分钟工作”......例如:
但是...用户整天都不工作(当然......)我怎么能进行这个查询?
对某些问题的回答:
答案 0 :(得分:1)
此查询执行此操作。
SELECT user, CAST(date AS DATE) day, (SUM(worked_seconds) / 60) minutes
FROM (
SELECT w1.user
, w1.date
, UNIX_TIMESTAMP(
LEAST(
MIN(IFNULL(w2.date, w1.date + INTERVAL 5 MINUTE)),
CAST(w1.date AS DATE) + INTERVAL 1 DAY
)
)
- UNIX_TIMESTAMP(w1.date) worked_seconds
FROM work w1
LEFT JOIN work w2
ON w1.user = w2.user
AND w1.date < w2.date
AND w1.date + INTERVAL 5 MINUTE > w2.date
AND CAST(w1.date AS DATE) = CAST(w2.date AS DATE)
GROUP BY w1.user, w1.date
) work
GROUP BY user, day
查询在5分钟的间隔内将每个工作行与同一用户的所有后续工作行(ON w1.user = w2.user)配对(AND w1.date&lt; w2.data AND w1.date + INTERVAL 5 MINUTE&gt; w2.date),前提是工作发生在同一天(CAST(w1.date AS DATE)= CAST(w2.date AS DATE)。
根据定义,特定日期的最后一行不会有后续行,因为我们使用LEFT JOIN,这将导致NULL值。我们假设对于最后一行,根据注销规则完成了5分钟的工作(IFNULL(w2.date,w1.date + INTERVAL 5 MINUTE)
对于每个(日期,用户)行,可能会找到多个以后的行,在这种情况下,我们希望找到最早的行,以便我们可以计算两个日期之间的差异。这是使用MIN功能完成的。
现在,由于最后一行+5分钟的间隔可能延长到一天结束,我们使用LEAST来防止这种情况发生。
UNIX_TIMESTAMP用于将日期时间转换为秒,因此我们可以轻松地将它们减去并获得工作秒数。
在外部查询中,最后我们对每个用户的工作进行SUM并除以60,以便从几秒钟到几分钟。