SQL_ Извлечение событий сбоя / восстановления для каждого пользователя, только если они являются последовательными - PullRequest
1 голос
/ 01 августа 2020

У меня есть таблица определенных событий сбоя и восстановления для пользователей. Я хотел бы найти разницу во времени между отказом и событием восстановления для каждого пользователя. Также для некоторых событий сбоя существует несколько событий восстановления, я хочу найти разницу во времени только между последовательными. И до восстановления может произойти несколько сбоев. Мне нужна только разница между последовательным отказом и восстановлением (игнорируя все ведущие и конечные дополнительные события для этого пользователя)

sr  imei            time                                event_type  
1    1              2020-01-01 14:28:06.269000+00:00    failure 
2    1              2020-01-01 14:28:29.910000+00:00    failure_restored    
3    5              2020-01-01 15:24:52.714000+00:00    failure 
4    5              2020-01-01 15:29:59.045000+00:00    failure_restored    
5    6              2020-01-01 21:21:32.715000+00:00    failure_restored    
6    7              2020-01-01 21:48:43.798000+00:00    failure_restored    
7    9              2020-01-01 22:18:34.112000+00:00    failure_restored    
8    9              2020-01-01 22:20:16.165000+00:00    failure 
9    9              2020-01-01 22:25:29.648000+00:00    failure_restored    

Я хочу найти разницу во времени между событиями failure / failure_restored для каждого imei. например: между строками 1 и 2, 3 и 4, строки 6, 7 и 8 следует игнорировать, а между строками 8 и 9.

Я мог бы добиться этого с помощью pandas с пользовательскими функциями, но нужна помощь делая это в SQL.

Ответы [ 2 ]

2 голосов
/ 02 августа 2020

Вы не указываете, что делать, если подряд два «сбоя». Если вы всегда знаете, что следующая строка является восстановлением, тогда:

SELECT imei, TIMESTAMP_DIFF(next_time, time, MILLISECOND) as time_diff_in_milliseconds
FROM (SELECT t.*,
             LEAD(time) OVER (PARTITION BY imei ORDER BY time) as next_time
      FROM t
     )
WHERE event_type = 'failure';

Если нет, то также проверьте следующий тип события:

SELECT imei, TIMESTAMP_DIFF(next_time, time, MILLISECOND) as time_diff_in_milliseconds
FROM (SELECT t.*,
             LEAD(time) OVER (PARTITION BY imei ORDER BY time) as next_time,
             LEAD(event_type) OVER (PARTITION BY imei ORDER BY time) as next_event_type
      FROM t
     )
WHERE event_type = 'failure' and next_event_type = 'failure-restored';
0 голосов
/ 01 августа 2020

Ниже для BigQuery Standard SQL

#standardSQL
SELECT imei, TIMESTAMP_DIFF(restore_time, time, MILLISECOND) time_diff_in_milliseconds
FROM (
  SELECT *, LEAD(IF(event_type = 'failure_restored', time, NULL)) OVER(PARTITION BY imei ORDER BY time) restore_time
  FROM `project.dataset.table`  
)
WHERE event_type = 'failure'   

если применить к образцу данных из вашего вопроса - результат будет

Row imei    time_diff_in_milliseconds    
1   1       23641    
2   5       306331   
3   9       313483   
...