【问题标题】:Inconsistency with add_months function in Hive?与 Hive 中的 add_months 函数不一致?
【发布时间】:2016-11-11 07:12:16
【问题描述】:

我已经在 SO 上潜伏了一段时间,但最后有我自己的问题,我在这里或谷歌上找不到。对不起,我的经验不足,只有几年离开学校。使用 Hive 1.2,我遇到了 add_months 函数似乎无法正常/一致地工作的情况。

简单来说,我基本上有一个带有 clientid、yyyy-MM 和 int 的表。

select clientid, concat(yearmonth, '-01'), integer, add_months(concat(yearmonth, '-01'), integer) 
from tablea
where yearmonth = '2015-04' group by clientid, yearmonth, integer;

我使用 where 语句,因为这似乎只影响 4 月和 11 月的日期。我发现会发生什么:

ClientID1, 2015-04-01, 1, 2015-05-01  
ClientID2, 2015-04-01, 1, 2015-05-01  
ClientID3, 2015-04-01, 1, 2015-05-01  
ClientID4, 2015-04-01, 1, 2014-04-30  
ClientID5, 2015-04-01, 1, 2014-04-30  
ClientID6, 2015-04-01, 1, 2014-04-30  

add_months 究竟是如何工作的? (阿帕奇链接:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF#LanguageManualUDF-DateFunctions)。此外,如果我包含另一个 where 语句,其中 add_months 结果 = '2014-04-30',我会返回实际显示 '2015-05-01' 的行。到底发生了什么?

如果我从表面上更改查询(将其简化或使其更复杂但基本相同),有时结果会发生变化。任何人都可以尝试复制这个并让我知道我不只是疯了吗?是否有任何四舍五入的事情或任何事情可能会搞砸?

【问题讨论】:

  • 试试SELECT clientid, concat(yearmonth, '-01'), integer, add_months(CAST(concat(yearmonth, '-01') AS DATE), integer) FROM tablea WHERE yearmonth = '2015-04' GROUP BY clientid, yearmonth, integer;
  • @MRSrinivas 我实际上正在考虑这样做。虽然我很困惑为什么它应该很重要,因为文档指出它需要日期/字符串/时间戳作为参数?不过现在会尝试。
  • @MRSrinivas 不走运;它似乎已经解决了 11 月而不是 4 月。我仍然对这只会影响某些月份的方式或原因感到困惑......

标签: date hadoop hive hql


【解决方案1】:

在处理日期时,请使用 DATE 格式的字段,因此引擎会处理其他事情,例如闰年或月份中的天数等(加/减)

确保您的字段没有空格或特殊字符,我有以下内容并且可以完美运行

文件 ClientID1, 2015-01,1 ClientID2, 2015-02,1 客户ID3, 2015-04,1 客户ID4, 2015-04,1 客户 ID5, 2015-05,1 客户ID6, 2015-06,1 客户ID7, 2015-07,1 客户ID8, 2015-08,1 客户 ID9, 2015-09,1 客户 ID10, 2015-10,1 客户ID11, 2015-11,1 ClientID12, 2015-12,1

Create table date_nov (client String, datemonth String, x int )  ROW FORMAT     DELIMITED FIELDS TERMINATED BY ",";
LOAD DATA INPATH '/user/root/date_nov.txt' into TABLE date_nov ;

hive> select * from date_nov;
OK
ClientID1        2015-01        1
ClientID2        2015-02        1
ClientID3        2015-04        1
ClientID4        2015-04        1
ClientID5        2015-05        1
ClientID6        2015-06        1
ClientID7        2015-07        1
ClientID8        2015-08        1
ClientID9        2015-09        1
ClientID10       2015-10        1
ClientID11       2015-11        1
ClientID12       2015-12        1

select * , add_months(to_DATE(concat(trim(datemonth),'-01' )),x)   from date_nov;

---------------------------------------

【讨论】:

  • 但是 add_months 上的文档声明它需要日期/字符串/时间戳作为参数?我也尝试过到目前为止 - 它似乎只有固定的 11 月日期。发生了一些可疑的事情......
  • 我已经用新的 SQL 进行了编辑,如果可行,请告诉我
  • 所以 99% 的时间,add_months 都按预期工作。进行任何简单的测试以尝试复制错误不会显示任何问题(正如您所测试的那样)。我似乎发现了它无法正常工作的情况——最近与高级数据架构师确认了这个错误。仍然不确定是什么触发了它,但是一旦我们有更多时间坐下来找出一个简单的复制,就会报告这个错误。不过感谢您的帮助!
  • 好的,遇到特殊数据问题时把数据发给我。
猜你喜欢
  • 2021-01-23
  • 2011-07-17
  • 2011-10-22
  • 2019-04-15
  • 2022-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多