【问题标题】:MySQL - Grouping Time Ranges by Fifteen Minute IntervalsMySQL - 按 15 分钟间隔对时间范围进行分组
【发布时间】:2018-05-17 20:55:49
【问题描述】:

所以,我有一个计时表,用于跟踪我的员工在登录不同状态时所花费的时间。看起来是这样的:

Employee_ID     Queue             StartTime            End Time
   121509      'Break'      2018-05-17 13:31:54  2018-05-17 13:47:02
   121509      'Working'    2018-05-17 13:47:04  2018-05-17 15:05:45
   121509      'Unavail.'   2018-05-17 15:05:46  2018-05-17 15:32:01

等等。我的目标是汇总所有员工在每个队列状态中花费的时间(通过从 EndTime 中减去 StartTime 得出),并将该汇总按 15 分钟间隔分组。我做的是这样的:

concat(
    time_format(convert_tz(StartTime,'UTC','America/Denver'),'%H'),
    ':',
    case
        when minute(convert_tz(StartTime,'UTC','America/Denver')) < 15
            then '00'
        when minute(convert_tz(StartTime,'UTC','America/Denver')) < 30
            then '15'
        when minute(convert_tz(StartTime,'UTC','America/Denver')) < 45
            then '30'
        else '45'
    end,
    ':00'
) as 'Interval',

但是,通过这种方式进行分组,我意识到如果我以这种方式对事物进行分组,那么在队列中花费的任何时间都将仅计入员工登录的第一个时间间隔,而不是拆分StartTime 和 Endtime 之间的时间范围所包围的所有间隔中的时间。

所以,我的问题是:我如何对我的数据进行分组,以便如果给定的时间范围超过了它开始的 15 分钟间隔,那么它就会开始为 下一个 15 分钟的间隔计数?

示例输出:

Employee_ID   Interval      Queue    QueueTime
   121509        13:30      'Break'   00:14:54
   121509        13:45      'Break'   00:02:02
   121509        13:45     'Working'  00:13:58
   121509        14:00     'Working'  00:15:00
   121509        14:15     'Working'  00:15:00
   121509        14:30     'Working'  00:02:58
   121509        14:30     'Unavail.' 00:08:13
   121509        14:30     'Break'    00:03:28

【问题讨论】:

  • 您可能会得到 StartTime 和 EndTime 的日期差异 (DATEDIFF(minute,StartTime,EndTime))。然后将其除以 15,得到每个员工有多少 15 分钟的间隔。
  • 你能添加你的预期输出吗?您是否尝试每 15 分钟生成一行?例如,在一天 8 小时内,您将有 32 行,时间间隔设置为 15 分钟?或者您是否尝试将花费的时间四舍五入到 15 分钟的间隔?
  • 这是一个 SQL fiddle,其中填充了您的表架构:sqlfiddle.com/#!9/4105f6
  • 理想情况下,输出将是一个包含 15 分钟间隔(15:00:00、15:15:00、15:30:00 等)的列表,以及员工花费的时间每个间隔中的每个队列。我在上面添加了一个示例。
  • @StevenDay 您将需要创建一个间隔表(每 15 分钟一行...例如 00,00;00,15,最多 23,30;23,45 ) 然后查询该表,同时从您的队列表中提取数据。我没有时间建立一个例子,但希望这会让事情取得进展。

标签: mysql sql time intervals


【解决方案1】:

我猜您会想要获取时间戳差异,然后按员工和队列类型分组。像这样的查询应该适合您:

SELECT 
    Employee_ID,
    Queue,
    SUM(TIMESTAMPDIFF(MINUTE,
        StartTime,
        EndTime)) AS Time
FROM
    EmployeeTable
GROUP BY Employee_ID , Queue;

【讨论】:

  • 我想要的,但按十五分钟间隔分组(即 15:00:00、15:15:00、15:30:00 等)我在主要问题中添加了我正在寻找的输出示例。
【解决方案2】:

好的。花了一些时间,但我在 RToyo 的帮助下弄明白了:

首先:创建一个包含 15 分钟间隔的列表:

        select 
        addtime(time('00:00:00'),sec_to_time(900 * (a.a + b.a * 10))) as 'IntervalStart',
        addtime(time('00:14:59'),sec_to_time(900 * (a.a + b.a * 10))) as 'IntervalEnd'
    from (
        select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
        cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    where
        addtime(time('00:00:00'),sec_to_time(900 * (a.a + b.a * 10))) between '06:00:00' and '18:45:00'

下一步:通过测试 StartTime 和 Endtime 字段之间的重叠来加入计时表:

left join (     select 
        addtime(time('00:00:00'),sec_to_time(900 * (a.a + b.a * 10))) as 'Interval Start',
        addtime(time('00:14:59'),sec_to_time(900 * (a.a + b.a * 10))) as 'Interval End'
    from (
        select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
        cross join (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
    where
        addtime(time('00:00:00'),sec_to_time(900 * (a.a + b.a * 10))) between '06:00:00' and '18:45:00') as Intervals
on timekeepingtable.StartTime <= Intervals.IntervalStart
and timekeepingtable.EndTime >= Intervals.IntervalEnd

然后只需将 StartTime 和 EndTime 字段修改为以间隔为界:

        if(time(pgrp.StartTime) < Intervals.IntervalStart,Intervals.IntervalStart,time(pgrp.StartTime)) as 'Start Time',
    if(time(pgrp.EndTime) > Intervals.IntervalEnd, Intervals.IntervalEnd,time(pgrp.EndTime)) as 'End Time',

【讨论】:

    猜你喜欢
    • 2011-02-17
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多