【问题标题】:Date comparison in HiveHive 中的日期比较
【发布时间】:2012-12-13 20:11:52
【问题描述】:

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

【问题讨论】:

    标签: hive timestamp hiveql ddl


    【解决方案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 ;
    

    【讨论】:

      【解决方案2】:

      怎么样:

      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 来完成。

      【讨论】:

      • 对我最终使用的解决方案的精彩解释。一个问题 - 在这种情况下,TIMESTAMP/STRINGINT 之间的比较是否可行?
      • 跟进 - TIMESTAMP/STRINGINT 比较作品。感谢您提供这些信息,它很好地简化了查询。
      【解决方案3】:

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

      中提供值

      yyyy-MM-dd HH:mm:ss

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

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

      使用这个简单的查询:

      select from_unixtime(unix_timestamp()), cast(unix_timestamp() as 时间戳)从 test_tt 限制 1;

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

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

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

      【讨论】:

      • 看起来这是在 HIVE-3454 中报告的,但由于 Hive 维护人员希望确保向后兼容损坏的行为,因此尚未进行任何工作来修复它。
      • @JeremiahPeschka 谢谢,还有解决方法...我也应该在那里搜索我的其他时间戳问题。
      【解决方案4】:

      您也可以使用 datediff。那么 where 子句将是
      如果是字符串时间戳(jdbc 格式):

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

      如果是 Unix 纪元时间:

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-31
          • 2018-11-24
          • 2022-11-18
          • 1970-01-01
          • 2015-04-17
          • 2017-01-19
          相关资源
          最近更新 更多