从MySQL中的日期时间间隔中提取统计信息

时间:2017-03-23 18:43:44

标签: mysql datetime

我有一个MySQL数据库,其中一些表存储为innoDB类型。其中一个是work_session,其结构是:

  • id int(10)unsigned auto_increment primary
  • project_id int(10)unsigned index
  • begin datetime
  • end datetime

该表用于记录每个项目花费的时间。当然,每行end都大于begin。多行可能具有相同的project_id,但具有相同begin的行的endproject_id表示的间隔不会重叠。

我的目标是从此表中提取一些统计数据。特别是:

  • 每个project_id
  • 花费的时间
  • 从第一个记录的活动到现在
  • ,每个project_id每天花费的时间
  • 每个project_id
  • 每小时花费的时间
  • 每个project_id
  • 每周的时间

我能够使用PHP实现这一目标,但我想学习如何使用MySQL。

我能够通过

获得第一个统计数据
SELECT 
  `project_id`,
  SUM(`work_session_duration`) AS `project_duration`
FROM
  (SELECT 
    `project_id`,
    TIMESTAMPDIFF(SECOND, `begin`, `end`) AS `work_session_duration`
   FROM `work_sessions`) AS `t1`
GROUP BY `project_id`

其他三个统计数据非常相似,特别是最后两个,但我无法通过MySQL找到解决方法。

2 个答案:

答案 0 :(得分:1)

我认为每小时统计数据是最困难的部分。所以我只会为它提供一个解决方案。其他问题可以用类似的方式解决。

您需要一些帮助表:

calendar

|    date    |
|------------|
| 1970-01-01 |
| 1970-01-02 |
| ...        |
| 1940-12-30 |
| 1940-12-31 |

hours

| hour |
|------|
|    0 |
|    1 |
|  ... |
|   22 |
|   23 |

您可以在SO上找到许多答案,如何创建此类表格。我将跳过那一部分来保持我的答案紧凑。

使用帮助程序表,您可以在子查询中创建CROSS JOIN,其中包含数据所需的任何日期 - 小时组合。该子查询可以在重叠时与您的表连接。然后,您可以按project_idh.hour进行分组,并计算工作时间总和:

select s.project_id, h.hour,
    sum(timestampdiff(second, greatest(s.begin, h.begin), least(s.end, h.end))) as project_duration
from (    
    select h.hour,
           timestamp(c.date, concat(h.hour, ':00:00')) as `begin`,
           timestamp(c.date, concat(h.hour+1, ':00:00')) as `end`
    from calendar c
    cross join hours h
    where c.date >= (select date(min(`begin`)) from work_sessions)
      and c.date <= (select date(max(`end`))   from work_sessions)
) h
inner join work_sessions s
    on  s.begin < h.end
    and s.end   > h.begin
group by s.project_id, h.hour

答案 1 :(得分:0)

你尝试过这样的事吗?

SELECT 
  `project_id`,
  SUM(`work_session_duration`) AS `project_duration`,
  `days`
FROM
  (SELECT 
    `project_id`,
    TIMESTAMPDIFF(SECOND, `begin`, `end`) AS `work_session_duration`,
    DATE_FORMAT(`begin`, '%Y-%m-%d') AS `days`
   FROM `work_sessions`) AS `t1`
GROUP BY `project_id`, `days`
ORDER BY `days`

SELECT 
  `project_id`,
  SUM(`work_session_duration`) AS `project_duration`,
  HOUR(`begin`) AS `hours`
FROM
  (SELECT 
    `project_id`,
    TIMESTAMPDIFF(SECOND, `begin`, `end`) AS `work_session_duration`,
    `begin`
   FROM `work_sessions`) AS `t1`
GROUP BY `project_id`, `hours`

SELECT 
  `project_id`,
  SUM(`work_session_duration`) AS `project_duration`,
  WEEKDAY(`begin`) AS `weekdays`
FROM
  (SELECT 
    `project_id`,
    TIMESTAMPDIFF(SECOND, `begin`, `end`) AS `work_session_duration`,
    `begin`
   FROM `work_sessions`) AS `t1`
GROUP BY `project_id`, `weekdays`

或类似的东西......