Определение интервала выборки для каждого уникального значения из временных меток в таблице HIVE

#sql #datetime #count #hiveql #window-functions

#sql #дата-время #количество #hiveql #окно-функции

Вопрос:

У меня есть таблица HIVE:

 device           timestamp            value
  d_1        2020-08-15 00:05:00       10
  d_1        2020-08-15 00:10:00       12
  d_1        2020-08-15 00:15:00       08
  d_2        2020-08-15 00:05:00       62
  d_2        2020-08-15 00:25:00       14
  d_2        2020-08-15 00:45:00       10
  

Обратите внимание, что устройство d_1 имеет другой временной интервал (5 секунд), чем устройство d_2 (20 секунд).

Для большой таблицы с миллионами строк, как я могу определить интервал выборки для всех уникальных устройств?

Я ищу вывод, подобный этому:

  device       sampling_interval(mins)   
  d_1                  5
  d_2                 20
  

Комментарии:

1. Что, если интервал выборки не является постоянным, скажем, на устройстве отсутствуют некоторые точки данных или его интервал изменяется?

Ответ №1:

Самым безопасным из возможных подходов было бы использовать lag() для вычисления продолжительности каждого интервала между последовательными точками данных одного и того же устройства, а затем подсчитывать, сколько раз выполнялся каждый интервал:

 select
    device,
    (unix_timestamp(ts) - unix_timestamp(lag_ts)) / 60 sampling_interval_minutes,
    count(*) no_hits
from (
    select 
        t.*, 
        lag(ts) over(partition by device order by ts) lag_ts
    from mytable t
) t
group by device, (unix_timestamp(ts) - unix_timestamp(lag_ts)) / 60 
order by device, no_hits desc
  

Это позволяет легко проверять согласованность интервалов и видеть, какой из них встречается чаще всего.

Комментарии:

1. Я получаю ошибки синтаксического анализа из этого запроса. Не уверен, как решить. В нем говорится, что рядом с EOF отсутствуют закрывающие скобки

2. @Cybernetic: исправлено

3. Просто чтобы быть уверенным, no_hits — это количество обращений, а не «нет обращений»

4. @Cybernetic: да, точно.

5. Спасибо. Ваш запрос выглядит великолепно, я просто не могу объяснить # hits, которые я получаю с интервалом времени 0. Я получаю правильное количество обращений за ожидаемые ненулевые временные интервалы (например, 5 минут), но я также получаю миллионы строк с временным интервалом 0. Почему для # hits должно быть так много нулей? Это 27-дневные отрезки времени, которые продолжают повторяться.

Ответ №2:

Вы можете получить среднюю разницу, используя:

 select device,
       (unix_timestamp(max(timestamp)) - unix_timestamp(min(timestamp))) / nullif(count(*) - 1, 0)
from t
group by device;
  

Это дает среднюю разницу во временных метках между строками.

Комментарии:

1. Я получаю неправильные значения. Для устройств, которые, как я знаю, имеют 5-минутные интервалы выборки, я получаю ~ 0,2. Это частота выборки (не интервал), но я не думаю, что это тоже вычисляется.

2. Есть ли способ сделать это без использования unixtimestamp? Я не думаю, что мои даты работают с unixtimestamp.

3. Это дает среднюю разницу в секундах для каждого устройства. unix_timestamp() должно работать с разумно отформатированным значением данных.