如何结合多个时间跨度

时间:2010-10-07 21:01:56

标签: mysql

可以说,我有下表

| start               | end                 | activity
+---------------------+---------------------+---------
| 2010-07-26 09:10:00 | 2010-07-26 09:21:00 | 6
| 2010-07-26 09:35:00 | 2010-07-26 09:47:00 | 5
| 2010-07-26 10:05:00 | 2010-07-26 10:45:00 | 5
| 2010-07-26 10:50:00 | 2010-07-26 11:22:00 | 6
| 2010-07-26 13:15:00 | 2010-07-26 13:43:00 | 7
| 2010-07-26 14:12:00 | 2010-07-26 14:55:00 | 2

我想结合小时间跨度,将平均分钟数与每小时活动数相加。这样的事情:

| start               | minutes_activity    | avg_activity
+---------------------+---------------------+---------
| 2010-07-26 09:00:00 | 42                  | {avg value}
| 2010-07-26 10:00:00 | 50                  | {avg value}
| 2010-07-26 11:00:00 | 22                  | {avg value}
| 2010-07-26 13:00:00 | 28                  | {avg value}
| 2010-07-26 14:00:00 | 43                  | {avg value}

请注意,某些记录可以在两小时内有活动分钟,即10:50:00 - 11:22:00。在这种情况下,应在10:00和22分钟到11:00之间添加10分钟。

一个解决方案,无论是MySql,PHP还是两者都很受欢迎。

谢谢你提前。

2 个答案:

答案 0 :(得分:2)

我们假设您的表名为records,并且您的时间间隔不会超过两个小时:

SELECT DISTINCT(CONCAT(date,' ',IF(LENGTH(hour)=1, CONCAT('0',hour), hour), ':00:00')) AS start,
       SUM(minutes) AS minutes_activity,
       FORMAT(avg(activity),0) AS avg_activity
FROM (
      SELECT date, hour, minutes, activity
      FROM (
            SELECT DATE(start) AS date,
                   HOUR(ADDDATE(start, INTERVAL 1 HOUR)) AS hour,
                   IF(HOUR(start) < HOUR(end), MINUTE(end), 0) AS minutes,
                   activity AS activity
            FROM records
            HAVING minutes>0
           ) t1
      UNION (
             SELECT DATE(ADDDATE(start, INTERVAL 1 DAY)) AS date,
                    HOUR(ADDDATE(start, INTERVAL 1 HOUR)) AS hour,
                    IF(HOUR(start) > HOUR(end), MINUTE(end), 0) AS minutes,
                    activity AS activity
             FROM records
             HAVING minutes>0
                    AND hour=0
            )
      UNION (
             SELECT DATE(start) AS date,
                    HOUR(start) AS hour,
                    IF(HOUR(start) < HOUR(end),
                       (60 - MINUTE(start)),
                       IF(
                          DATE(start) < DATE(end),
                          (60 - MINUTE(start)),
                          (MINUTE(end) - MINUTE(start))
                       )
                    ) AS minutes,
                    activity AS activity
             FROM records
            )
      ORDER BY date ASC, hour ASC) t2
GROUP BY CONCAT(date,' ',IF(LENGTH(hour)=1, CONCAT('0',hour), hour), ':00:00');

...但是,如果你的间隔是从例如2010-10-08 01:30:002010-10-08 03:13:00,一个(不那么)简单的SQL查询不会这样做。

答案 1 :(得分:0)

我将为您概述一个解决方案(蛮力):

  1. 从数据库获取所有数据到PHP(按原样)
  2. 每隔一小时获取一个空数组
  3. 循环所有数据并获取start小时开始的时间戳(即向下舍入start);获取计算的起始参考点与您的startend values之间的小时数(作为花车)
  4. 通过提取此数据,您可以非常轻松地(少数ifwhile)将您的活动与小时分开,然后将它们从2添加到数组中。
  5. 此时,您将按一小时间隔分配所有数据。继续进行必要的处理。
  6. 我建议在计算时间戳时使用strtotime,因为你有标准的时间格式。为了增加一小时的时间,您可以使用strtotime('+1 hour', $timestamp)