Вопрос:
Привет, я пытаюсь выяснить, какая разница между использованием TRUNC и TO_DATE в Hive.
В настоящее время в oracle я написал следующий пример case в отношении данных, показанных ниже:
ORDER_NO | NAME | DATE_ | TASK_NO ABC123 | Humpty | 07-OCT-16 12:30:54 | 1 ABC123 | Humpty | 07-OCT-16 12:30:54 | 2 ABC123 | Humpty | 07-OCT-16 12:32:20 | 6 SELECT ORDER_NO, NAME, DATE_, TASK_NO (CASE WHEN DATE_ — LAG(DATE_) OVER (PARTITION BY ORDER_NO, NAME, TRUNC(DATE_) ORDER BY DATE_) <= 1/48 THEN 0 ELSE 1 END) AS COUNT1
и это дает мне результат:
ORDER_NO | NAME | DATE_ | TASK_NO | COUNT1 ABC123 | Humpty | 07-OCT-16 12:30:54 | 1 | 1 ABC123 | Humpty | 07-OCT-16 12:30:54 | 2 | 0 ABC123 | Humpty | 07-OCT-16 12:32:20 | 6 | 1
что является правильным. Теперь, если я использую тот же запрос в Hive против моего полного набора данных, я получаю сообщение об ошибке:
Error while compiling statement: FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns.
Итак, я изменил TRUNC на TO_DATE, и это работает и дает мне следующие результаты:
SELECT ORDER_NO, NAME, DATE_, TASK_NO (CASE WHEN DATE_ — LAG(DATE_) OVER (PARTITION BY ORDER_NO, NAME, TO_DATE(DATE_) ORDER BY DATE_) <= 1/48 THEN 0 ELSE 1 END) AS COUNT1
и это дает мне результат:
ORDER_NO | NAME | DATE_ | TASK_NO | COUNT1 ABC123 | Humpty | 07-OCT-16 12:30:54 | 1 | 1 ABC123 | Humpty | 07-OCT-16 12:32:20 | 6 | 1 ABC123 | Humpty | 07-OCT-16 12:30:54 | 2 | 1
который отличается от того, что я получаю в Oracle. Из того, что я могу собрать, значение даты хранится в виде строки в качестве результата arent, упорядоченного в Date/Time, и здесь я думаю, что проблема неясна, но не знаю, какие изменения мне нужно сделать, чтобы исправить ее.
Был бы очень признателен за некоторые советы.
ОБНОВЛЕННЫЙ КОД:
SELECT ORDER_NO ,NAME ,DATE_FIXED ,TASK_NO ,CASE WHEN DATE_UTS — LAG(DATE_UTS) OVER (PARTITION BY ORDER_NO, NAME, TO_DATE(DATE_FIXED) ORDER BY DATE_FIXED) <= 60*30 THEN 0 ELSE 1 END AS COUNT1 FROM ( SELECT ORDER_NO ,NAME ,TASK_NO ,FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_, ‘DD-MMM-YY HH:MM:SS’)) AS DATE_FIXED ,UNIX_TIMESTAMP(DATE_, ‘DD-MMM-YY HH:MM:SS’) AS DATE_UTS FROM TABLE1 ) T Лучший ответ:Содержание
1
Операторы улей и пользовательские функции (UDF)
to_date
Возвращает часть даты строки timestamp (pre-Hive 2.1.0):
to_date ( “1970-01-01 00:00:00” ) = “1970-01-01”.
Начиная с Hive 2.1.0, возвращает объект даты.
До Hive 2.1.0 (HIVE-13248) тип возврата был строкой, потому что при создании метода не существовал тип даты.
trunc
Возвращает дату, усеченную до единицы, указанной в формате (по состоянию на Hive 1.2.0).
Поддерживаемые форматы: MONTH/MON/MM, YEAR/YYYY/YY.
Пример: trunc (‘2015-03-17’, ‘MM’) = 2015-03-01.
2
У вас есть ошибки в исходном запросе
- Не было запятой между TASK_NO и (CASE WHEN
- Trunc в Hive должен принимать 1 параметр, а для дня нет параметра.
- Нет оператора минус для дат (и определенно не для строк). В результате получается NULL.
3
Единственный формат даты распознавания в Hive – YYYY-MM-DD, который не соответствует вашим данным.
Применение функций даты на недопустимой строке приводит к NULL.
Вот как вы конвертируете формат данных в даты:
hive> select from_unixtime(unix_timestamp(’07-OCT-16 12:30:54′,’dd-MMM-yy HH:mm:ss’)); OK 2016-10-07 12:30:54
и весь запрос:
select ORDER_NO ,NAME ,DATE_fixed ,TASK_NO ,case when DATE_uts — LAG(DATE_uts) OVER ( PARTITION BY ORDER_NO,NAME,to_date(DATE_fixed) ORDER BY DATE_fixed ) <= 60*30 then 0 else 1 end AS COUNT1 from (select ORDER_NO ,NAME ,TASK_NO ,from_unixtime(unix_timestamp(DATE_,’dd-MMM-yy HH:mm:ss’)) as DATE_fixed ,unix_timestamp(DATE_,’dd-MMM-yy HH:mm:ss’) as DATE_uts from t ) t ; ABC123 Humpty 2016-10-07 12:30:54 2 1 ABC123 Humpty 2016-10-07 12:30:54 1 0 ABC123 Humpty 2016-10-07 12:32:20 6 0
Это были также результаты, когда я тестировал его на Oracle