我正在使用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中执行日期比较的适当方法是什么?
答案 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:
unix_timestamp()
返回一个int:当前时间(以纪元为单位),以秒为单位from_unixtime(,'yyyy-MM-dd')
转换为给定格式的字符串,例如'2012-12-28'date_sub(,180)
从该字符串中减去180天,并以相同的格式返回一个新字符串。unix_timestamp(,'yyyy-MM-dd')
将该字符串转换回int 如果这一切都变得太毛茸茸,你总是可以写一个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 ;