MySQL - группировка временных диапазонов по пятнадцатиминутным интервалам - PullRequest
0 голосов
/ 17 мая 2018

Итак, у меня есть таблица учета рабочего времени, которая отслеживает, сколько времени мои сотрудники проводят в разных штатах. Это выглядит так:

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

И так далее. Моя цель - агрегировать количество времени, которое все сотрудники тратят в каждом состоянии очереди (определяется путем вычитания StartTime из EndTime), и группировать это агрегирование по пятнадцатиминутным интервалам. То, что я делал, было так:

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',

Однако, сгруппировав таким образом, я понял, что если бы я сгруппировал вещи таким образом, то любое время, проведенное в очереди, будет засчитываться только для интервала first , в который вошел сотрудник, а не для разделения время среди всех интервалов, охватываемых временным диапазоном между StartTime и Endtime.

Итак, мой вопрос: как мне сгруппировать мои данные так, чтобы, если заданный временной диапазон превышал пятнадцатиминутный интервал, в котором он был запущен, он начинал считать * следующий следующий за пятнадцатиминутный интервал?

Пример вывода:

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

Ответы [ 2 ]

0 голосов
/ 18 мая 2018

Хорошо. Это заняло некоторое время, но я понял это с помощью RToyo:

Первый: создать список из пятнадцатиминутных интервалов:

        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',
0 голосов
/ 18 мая 2018

Полагаю, вы захотите получить разницу во времени, а затем сгруппировать по сотруднику и типу очереди.Такой запрос должен работать для вас:

SELECT 
    Employee_ID,
    Queue,
    SUM(TIMESTAMPDIFF(MINUTE,
        StartTime,
        EndTime)) AS Time
FROM
    EmployeeTable
GROUP BY Employee_ID , Queue;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...