Разница во времени на человека между последовательными рядами - PullRequest
0 голосов
/ 14 октября 2019

У меня есть некоторые данные, которые (в широком смысле) состоят из следующих полей:

Person  TaskID   Start_time                      End_time
Alpha   1       'Wed, 18 Oct 2017 10:10:03 GMT' 'Wed. 18 Oct 2017 10:10:36 GMT'
Alpha   2       'Wed, 18 Oct 2017 10:11:16 GMT' 'Wed, 18 Oct 2017 10:11:28 GMT'
Beta    1       'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:12:49 GMT'
Alpha   3       'Wed, 18 Oct 2017 10:12:03 GMT' 'Wed, 18 Oct 2017 10:13:13 GMT'
Gamma   1       'Fri, 27 Oct 2017 22:57:12 GMT' 'Sat, 28 Oct 2017 02:00:54 GMT'
Beta    2       'Wed, 18 Oct 2017 10:13:40 GMT' 'Wed, 18 Oct 2017 10:14:03 GMT'

Для этих данных мой требуемый вывод выглядит примерно так:

Person  TaskID Time_between_attempts
Alpha   1      NULL      ['Wed, 18 Oct 2017 10:10:03 GMT' - NULL]
Alpha   2      0:00:40   ['Wed, 18 Oct 2017 10:11:16 GMT' -'Wed, 18 Oct 2017 10:10:36 GMT']
Beta    1      NULL      ['Wed, 18 Oct 2017 10:12:03 GMT' - NULL]
Alpha   3      0:00:35   ['Wed, 18 Oct 2017 10:12:03 GMT' -'Wed, 18 Oct 2017 10:11:28 GMT']
Gamma   1      NULL      ['Fri, 27 Oct 2017 22:57:12 GMT' - NULL]
Beta    2      0:00:51   ['Wed, 18 Oct 2017 10:13:40 GMT' -'Wed, 18 Oct 2017 10:12:49 GMT']

Мои требованияниже:

a. Для данного человека (Альфа, Бета или Гамма) первое вхождение переменной time_between_attempts будет равно нулю / NULL - в примере, который я показал как NULL.

b. Второй (и последующий) раз, когда появляется один и тот же человек, будет иметь ненулевое или ненулевое значение time_between_attempts. Эта переменная рассчитывается путем взятия разницы между временем окончания предыдущего задания и временем начала следующего задания.

В связи с этим у меня возникает следующий вопрос:

  1. Как выполнитьнаписать сценарий SQL, который может помочь мне достичь желаемого результата?

Обратите внимание, что TaskID записан как целое число только для упрощения. В исходных данных TaskID сложен и состоит из непостоянных строк, таких как:

'q:1392763916495:441',
'q:1392763916495:436'

Буду признателен за любые советы по этому вопросу.

Ответы [ 2 ]

1 голос
/ 14 октября 2019

Использование метода self Join ().

    SELECT a.person, 
            a.taskid, 
            TIMEDIFF (DATE_FORMAT(STR_TO_DATE(a.Start_time, '%a, %d %b %Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s') ,DATE_FORMAT(STR_TO_DATE(b.End_time, '%a, %d %b %Y %H:%i:%s'), '%Y-%m-%d %H:%i:%s') ) as Time_between_attempts,
            a.Start_time,
            b.End_time

        FROM   test a 
            LEFT JOIN test b 
                    ON a.person = b.person 
                        AND a.taskid = b.taskid + 1 
        ORDER  BY 1, 2; 

Но при этом будет игнорироваться часовой пояс.

1 голос
/ 14 октября 2019

Это отвечает оригинальной версии вопроса.

Вы можете использовать lag() и timestampdiff() для расчета. Предполагая, что ваше значение является реальной датой / временем или временной меткой, вы можете легко вычислить значение в секундах:

select t.*,
       timestampdiff(start_time,
                     lag(end_time) over (partition by person_id order by start_time)
                     seconds
                    )
from t;

Если значения сохраняются в виде строки, исправьте данные! В то же время вы можете использовать str_to_date() в функции.

Чтобы получить это как значение времени:

select t.*,
       (time(0) +
        interval timestampdiff(start_time,
                               lag(end_time) over (partition by person_id order by start_time)
                               seconds
                              ) second
       )
from t;
...