2014-09-01 159 views
0

我使用Hive臨時宏來幫助使用日期代數(在此情況下查找前一個月的第一天),並且獲得意外結果。Hive宏未返回預期結果

創建臨時宏month1st_sub(DT日期)
投(CONCAT(
情況
月時(DT)= 1,則投(年(DT)-1作爲字符串)
其他投(一年(DT)作爲字符串)
端,
「 - 」,
情況
當月(DT)= 1,則 「12」
別的鑄(月(DT)-1作爲字符串)
end,
「-01」
)as date)
;

當我使用包含用於max_dt(2014年8月15日)的單個值的VARS表使用測試該宏執行以下操作:

選擇
max_dt,
month1st_sub(鑄造( 「2013年1月1日」 爲日)),
month1st_sub(max_dt),
month1st_sub(鑄造( 「2013年1月1日」 爲日)),
month1st_sub(鑄造( 「2013年4月1日」作爲日期)),
m onth1st_sub(cast(「2013-5-1」as date)),
month1st_sub(cast(「2013-6-1」as date))
from vars;

我收到以下輸出:

max_dt _c1 _c2 _c3 _c4 _c5 _c6
2013年8月1日2012年12月1日2013-07-01 2012年12月1日2013-03 -01 2013-04-01 2013-07-01

上次返回的值2013-07-01應該是2013-05-01。這個錯誤是可重現的,如果我刪除6-1線,然後5-1線將返回2013-07-01。該問題似乎始終與一組宏調用的最後返回值一起出現。

我使用用途設置如下:

組hive.cli.print.header = TRUE;
set mapreduce.input.fileinputformat.split.maxsize = 10000000;
set hive.auto.convert.join = true;
set hive.exec.dynamic.partition.mode = nonstrict;

問題1:我做錯了什麼?如果不是這是Hive的問題還是可能是一些環境問題?
問題2:蜂巢中的臨時宏功能是否值得使用,還是應該編寫java udfs來執行此操作?

+0

我不知道爲什麼宏不起作用,但你可以隨時編寫和UDF爲此。這是一個很好的開始 - https://github.com/nexr/hive-udf/blob/master/src/main/java/com/nexr/platform/hive/udf/UDFLastDay.java – visakh 2014-09-02 12:59:00

+0

謝謝@visakh,the真正令我擔憂的是輸出的不一致性。我認爲我現在會選擇JAVA UDF路線,因爲它看起來更加完善了。 – brosplit 2014-09-02 14:46:48

回答

1

老問題,我知道。

宏實現中有許多重要的錯誤,這些錯誤應該主要由2.1.0解決。從https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

由於Hive 0.12.0。

錯誤修正:蜂巢1.3.0和2.0.0之前:

當HiveQL宏被多次使用,同時處理在同一行, 蜂巢返回相同的結果,即使該 所有調用辯論是不同的。 (見HIVE-11432)

在Hive 1.3.0和2.0.0之前: 在處理同一行時使用多個宏時,ORDER BY子句可能會給出錯誤的結果。 (見HIVE-12277。)

之前蜂巢2.1.0: 當同時處理相同的 行的多個宏中所使用的,以後的宏結果由該 第一個的覆蓋。 (見HIVE-13372)

我會建議更新配置單元到這兩個版本之一來解決您的問題。