Выявление пробелов в данных с использованием только временных меток - PullRequest
2 голосов
/ 27 марта 2019

Я пытаюсь выяснить запрос к данным Google BigQuery, который позволит мне определить, где существуют пробелы, в данных, которые имеют только временные метки (т. Е. Нет даты начала и окончания), данные обрабатываютсяупорядочены по этой временной отметке, и в строках есть непоследовательные идентификационные номера.

Sample data:

Row     localised_sample_date_time  
1       2019-03-21T00:00:29
2       2019-03-21T00:01:29
3       2019-03-21T00:02:29
4       2019-03-21T00:04:29
3       2019-03-21T00:05:29

Каждая строка данных содержит временную отметку, и ожидается, что каждая строка данных будет происходить в предсказуемый интервал времени (например, 10мин).Я ищу запрос, который иллюстрирует, где есть пробелы в данных, т.е. когда ожидаемая строка «10 минут» отсутствует.

Я хочу, чтобы данные выглядели примерно так:

data island
-------------------------------------------------------
[start timestamp of island] - [end timestamp of island]

например,

data island
-------------------------------------------------------
2019-03-21T00:00:29 - 2019-03-21T00:02:29
2019-03-21T00:04:29 - 2019-03-21T00:05:29

Логически я ищу что-то вроде:

  • порядок по метке времени
  • выяснить, если последовательные записи имеют 10 минутразрыв между ними
  • если они этого не делают, выведите начальную и конечную метки времени, представляющие остров данных.

Это хороший общий ресурс, объясняющий, как идентифицировать пробелы в данныхи острова - http://www.kodyaz.com/t-sql/data-islands-and-data-gaps-with-boundaries-using-sql.aspx - похоже, они не охватывают данные, структурированные так, как мои.

Я думаю, что должно быть что-то, что я могу использовать, что-то делает с DATEADD, ORDER BY и GROUP BY, чтобы определить группы записей, которые соответствуют ожидаемому шаблону 10-минутных интервалов, однако я не понимаю, как мне нужно реализовать то, что я пытаюсь достичь.Что такое элегантное, простое решение?

1 Ответ

2 голосов
/ 27 марта 2019

Ниже для BigQuery Standard SQL

#standardSQL
SELECT CONCAT(
    FORMAT_TIMESTAMP('%F %T', MIN(IF(gap, ts, previous_ts))), ' - ', FORMAT_TIMESTAMP('%F %T', MAX(ts))
  ) data_island
FROM (
  SELECT ts, previous_ts, gap, COUNTIF(gap) OVER(ORDER BY ts) grp
  FROM (
    SELECT ts, LAG(ts) OVER(ORDER BY ts) previous_ts,
      IFNULL(TIMESTAMP_DIFF(ts, LAG(ts, 1) OVER(ORDER BY ts), MINUTE), 2) > 1 gap
    FROM `project.dataset.table` 
  )
)
GROUP BY grp

Вы можете проверить, поиграть с выше, используя пример данных из вашего вопроса, как в примере ниже

#standardSQL
WITH `project.dataset.table` AS (
  SELECT TIMESTAMP '2019-03-21T00:00:29' ts UNION ALL
  SELECT '2019-03-21T00:01:29' UNION ALL
  SELECT '2019-03-21T00:02:29' UNION ALL
  SELECT '2019-03-21T00:04:29' UNION ALL
  SELECT '2019-03-21T00:05:29' 
)
SELECT CONCAT(
    FORMAT_TIMESTAMP('%F %T', MIN(IF(gap, ts, previous_ts))), ' - ', FORMAT_TIMESTAMP('%F %T', MAX(ts))
  ) data_island
FROM (
  SELECT ts, previous_ts, gap, COUNTIF(gap) OVER(ORDER BY ts) grp
  FROM (
    SELECT ts, LAG(ts) OVER(ORDER BY ts) previous_ts,
      IFNULL(TIMESTAMP_DIFF(ts, LAG(ts, 1) OVER(ORDER BY ts), MINUTE), 2) > 1 gap
    FROM `project.dataset.table` 
  )
)
GROUP BY grp
-- ORDER BY grp

с результатом

Row data_island  
1   2019-03-21 00:00:29 - 2019-03-21 00:02:29    
2   2019-03-21 00:04:29 - 2019-03-21 00:05:29    
...