11

我正在使用 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 中执行日期比较的适当方法是什么?

4

5 回答 5

14

怎么样:

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

如果您可以使用实际的时间戳值来计算,那么日期数学通常是最简单的。

还是您希望它只在一整天内切断?然后我认为问题在于您如何在整数和字符串之间来回转换。尝试:

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

如果这一切都变得太麻烦,您总是可以编写一个 UDF 自己来做。

于 2012-12-28T17:54:33.510 回答
6

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

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

如果是 Unix 纪元时间:

datediff(from_unixtime(unix_timestamp()), from_unixtime(created)) < 180;
于 2012-12-29T00:55:55.647 回答
3

我认为这可能是处理时间戳类型的 Hive 错误。我最近一直在尝试使用它并得到不正确的结果。如果我将您的架构更改为使用字符串而不是时间戳,并在

yyyy-MM-dd HH:mm:ss

格式,然后选择查询对我有用。

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

用这个简单的查询:

select from_unixtime(unix_timestamp()), cast(unix_timestamp() as timestamp) from test_tt limit 1;

我希望这两个字段是相同的,但我得到:

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

我也看到了其他奇怪的东西。

于 2012-12-29T00:52:46.353 回答
3

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

where created > 1000 * date_sub(from_unixtime(unix_timestamp()), 180);
于 2013-10-27T21:40:54.750 回答
1

在查看此内容并参考Hive 中不到 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 ;
于 2012-12-28T16:54:29.000 回答