#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()
должно работать с разумно отформатированным значением данных.