Сравнение дат в Hive
Я работаю с Hive, и у меня есть таблица, структурированная следующим образом:
CREATE TABLE t1 (
id INT,
created TIMESTAMP,
some_value BIGINT
);
мне нужно найти все строки t1
то чем 180 дней старых. Следующий запрос не дает строк, даже если в таблице присутствуют данные, соответствующие предикату поиска.
select *
from t1
where created > date_sub(from_unixtime(unix_timestamp()), 180);
каков подходящий способ выполнить сравнение дат в Hive?
5 ответов
как насчет:
where unix_timestamp() - created < 180 * 24 * 60 * 60
дата математика обычно проще, если вы можете просто сделать это с фактическими значениями метки времени.
или вы хотите, чтобы сократить только на целые дни? Тогда я думаю, что проблема в том, как вы конвертируете туда и обратно между ints и строками. Попробуйте:
where created > unix_timestamp(date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),180),'yyyy-MM-dd')
прогулка по каждому UDF:
-
unix_timestamp()
возвращает int: текущее время в секундах с начала эпохи -
from_unixtime(,'yyyy-MM-dd')
преобразуется в строку данный формат, например, '2012-12-28' -
date_sub(,180)
вычитает 180 дней от этой строки, и возвращает новую строку в том же формате. -
unix_timestamp(,'yyyy-MM-dd')
преобразует эту строку в int
если это все становится слишком волосатым, вы всегда можете написать UDF, чтобы сделать это самостоятельно.
в качестве альтернативы вы можете также использовать datediff. Тогда предложение будет
в случае Строковой метки времени (формат jdbc):
datediff(from_unixtime(unix_timestamp()), created) < 180;
в случае времени эпохи Unix:
datediff(from_unixtime(unix_timestamp()), from_unixtime(created)) < 180;
Я думаю, что, возможно, это ошибка улья, связанная с метка тип. Я пытался использовать его в последнее время и получив неверные результаты. Если я изменю вашу схему, чтобы использовать строку вместо timestamp, и значения в
гггг-ММ-ДД чч:мм:СС
формат, затем запрос select работал для меня.
согласно документации, улей должен иметь возможность конвертировать BIGINT, представляющий секунды эпохи в метка времени и что все существующие UDFs datetime работают с типом данных метки времени.
с этим простым запросом:
выберите from_unixtime (unix_timestamp ()), cast (unix_timestamp () как timestamp) от предела test_tt 1;
Я ожидал бы, что оба поля будут одинаковыми, но я получаю:
2012-12-29 00:47:43 1970-01-16 16:52:22.063
Я вижу и другие странности.
метка времени-миллисекунды
unix_timestamp в секундах
Вам нужно умножить RHS на 1000.
where created > 1000 * date_sub(from_unixtime(unix_timestamp()), 180);
после просмотра этого и ссылки на разница дат менее 15 минут в улье Я придумал решение. Хотя я не уверен, почему Hive не выполняет сравнение эффективно по датам как строкам (они должны сортировать и сравнивать лексикографически), работает следующее решение:
FROM (
SELECT id, value,
unix_timestamp(created) c_ts,
unix_timestamp(date_sub(from_unixtime(unix_timestamp()), 180), 'yyyy-MM-dd') c180_ts
FROM t1
) x
JOIN t1 t ON x.id = t.id
SELECT to_date(t.Created),
x.id, AVG(COALESCE(x.HighestPrice, 0)), AVG(COALESCE(x.LowestPrice, 0))
WHERE unix_timestamp(t.Created) > x.c180_ts
GROUP BY to_date(t.Created), x.id ;