Hive中的日期比较

时间:2012-12-28 15:13:16

标签: hive timestamp hiveql ddl

我正在使用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 个答案:

答案 0 :(得分:13)

怎么样:

where unix_timestamp() - created < 180 * 24 * 60 * 60

如果你可以用实际的时间戳值来做日期数学通常是最简单的。

或者你想要它只在整天被切断?然后我认为问题在于如何在int和字符串之间来回转换。尝试:

where created > unix_timestamp(date_sub(from_unixtime(unix_timestamp(),'yyyy-MM-dd'),180),'yyyy-MM-dd')

遍历每个UDF:

  1. unix_timestamp()返回一个int:当前时间(以纪元为单位),以秒为单位
  2. from_unixtime(,'yyyy-MM-dd')转换为给定格式的字符串,例如'2012-12-28'
  3. date_sub(,180)从该字符串中减去180天,并以相同的格式返回一个新字符串。
  4. unix_timestamp(,'yyyy-MM-dd')将该字符串转换回int
  5. 如果这一切都变得太毛茸茸,你总是可以写一个UDF来自己做。

答案 1 :(得分:6)

或者您也可以使用 datediff 。然后where子句将是
在String时间戳(jdbc格式)的情况下:

datediff(from_unixtime(unix_timestamp()), created) < 180;

在Unix纪元时间:

datediff(from_unixtime(unix_timestamp()), from_unixtime(created)) < 180;

答案 2 :(得分:3)

我想也许这是处理时间戳类型的Hive错误。我最近一直试图使用它并得到不正确的结果。 如果我更改架构以使用字符串而不是时间戳,并在

中提供值
   yyyy-MM-dd HH:mm:ss

格式,然后选择查询为我工作。

根据文档,Hive应该能够将表示纪元秒的BIGINT转换为时间戳,并且所有现有的日期时间UDF都可以使用时间戳数据类型。

使用这个简单的查询:

  

选择from_unixtime(unix_timestamp()),cast(unix_timestamp()as   时间戳)来自test_tt limit 1;

我希望两个字段都相同,但我得到:

  

2012-12-29 00:47:43 1970-01-16 16:52:22.063

我也看到了其他的怪异。

答案 3 :(得分:3)

TIMESTAMP是毫秒
unix_timestamp以秒为单位 您需要将RHS乘以1000。

where created > 1000 * date_sub(from_unixtime(unix_timestamp()), 180);

答案 4 :(得分:1)

在对此进行审核并参考Date Difference less than 15 minutes in Hive之后,我想出了一个解决方案。虽然我不确定为什么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 ;