【问题标题】:What is the difference between TRUNC and TO_DATE in HiveHive 中的 TRUNC 和 TO_DATE 有什么区别
【发布时间】:2016-12-22 14:38:47
【问题描述】:

嗨,我试图找出在 Hive 中使用 TRUNC 和 TO_DATE 之间的区别。

目前在 oracle 中,我针对如下所示的数据编写了以下案例语句:

ORDER_NO | NAME | DATE_ | TASK_NO
ABC123 | Humpty | 07-OCT-16 12:30:54 | 1
ABC123 | Humpty | 07-OCT-16 12:30:54 | 2
ABC123 | Humpty | 07-OCT-16 12:32:20 | 6

SELECT ORDER_NO, NAME, DATE_, TASK_NO
    (CASE WHEN DATE_ - LAG(DATE_) OVER (PARTITION BY ORDER_NO, NAME, TRUNC(DATE_) ORDER BY DATE_) <= 1/48  
    THEN 0 ELSE 1 END) AS COUNT1

这给了我结果:

ORDER_NO | NAME | DATE_ | TASK_NO | COUNT1
    ABC123 | Humpty | 07-OCT-16 12:30:54 | 1 | 1
    ABC123 | Humpty | 07-OCT-16 12:30:54 | 2 | 0
    ABC123 | Humpty | 07-OCT-16 12:32:20 | 6 | 1

这是正确的。现在,如果我在 Hive 中对我的完整数据集使用相同的查询,我会收到一条错误消息:

Error while compiling statement: FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns.

因此,我将 TRUNC 更改为 TO_DATE,这可以正常工作并得到以下结果:

SELECT ORDER_NO, NAME, DATE_, TASK_NO
(CASE WHEN DATE_ - LAG(DATE_) OVER (PARTITION BY ORDER_NO, NAME, TO_DATE(DATE_) ORDER BY DATE_) <= 1/48  
    THEN 0 ELSE 1 END) AS COUNT1

这给了我结果:

ORDER_NO | NAME | DATE_ | TASK_NO | COUNT1
ABC123 | Humpty | 07-OCT-16 12:30:54 | 1 | 1
ABC123 | Humpty | 07-OCT-16 12:32:20 | 6 | 1        
ABC123 | Humpty | 07-OCT-16 12:30:54 | 2 | 1

这与我在 Oracle 中得到的不同。从我可以收集到的数据中,日期值存储为字符串,因为结果不是按日期/时间排序的,这就是我认为问题所在,但不确定我需要进行哪些更改来修复它。

非常感谢一些建议。


更新代码:

SELECT  
ORDER_NO
,NAME
,DATE_FIXED
,TASK_NO
,CASE WHEN DATE_UTS - LAG(DATE_UTS) OVER (PARTITION BY ORDER_NO, NAME, TO_DATE(DATE_FIXED) ORDER BY DATE_FIXED) <= 60*30
THEN    0
ELSE    1
END AS COUNT1
FROM
(
SELECT
ORDER_NO
,NAME
,TASK_NO
,FROM_UNIXTIME(UNIX_TIMESTAMP(DATE_, 'DD-MMM-YY HH:MM:SS')) AS DATE_FIXED
,UNIX_TIMESTAMP(DATE_, 'DD-MMM-YY HH:MM:SS') AS DATE_UTS
FROM TABLE1
) T

【问题讨论】:

  • DATE_ 的列类型是什么?
  • 感谢 Kacper,oracle 中的 DATE_ 已作为日期数据类型关闭。
  • 什么是 DATE_ 类型是 Hive?
  • Hive 中的 DATE_ 类型以字符串形式出现。

标签: sql oracle hadoop


【解决方案1】:

1

Hive Operators and User-Defined Functions (UDFs)

到日期

返回时间戳字符串的日期部分(Hive 2.1.0 之前的版本):
to_date("1970-01-01 00:00:00") = "1970-01-01"。
从 Hive 2.1.0 开始,返回一个日期对象。
在 Hive 2.1.0 (HIVE-13248) 之前,返回类型是 String,因为在创建方法时不存在 Date 类型。


截断

返回截断为格式指定单位的日期(从 Hive 开始) 1.2.0).
支持的格式:MONTH/MON/MM、YEAR/YYYY/YY。
示例:trunc('2015-03-17', 'MM') = 2015-03-01。

2

您的原始查询中有错误

  1. TASK_NO(CASE WHEN 之间没有逗号
  2. Hive中的Trunc必须带1个参数,天没有参数。
  3. 日期没有减号运算符(当然也没有字符串)。这会导致 NULL。

3

Hive 中唯一可识别的日期格式是 YYYY-MM-DD,它与您的数据不匹配。
对无效字符串应用日期函数会导致 NULL。

这是您将数据格式转换为日期的方式:

hive> select from_unixtime(unix_timestamp('07-OCT-16 12:30:54','dd-MMM-yy HH:mm:ss'));
OK
2016-10-07 12:30:54

以及整个查询:

select  ORDER_NO
       ,NAME
       ,DATE_fixed
       ,TASK_NO
       
       ,case 
            when    DATE_uts 
                -   LAG(DATE_uts) OVER 
                    (
                        PARTITION BY    ORDER_NO,NAME,to_date(DATE_fixed) 
                        ORDER BY        DATE_fixed
                    )
                <= 60*30
            then    0
            else    1
        end             AS COUNT1
    
from   (select  ORDER_NO
               ,NAME
               ,TASK_NO
               ,from_unixtime(unix_timestamp(DATE_,'dd-MMM-yy HH:mm:ss'))   as DATE_fixed
               ,unix_timestamp(DATE_,'dd-MMM-yy HH:mm:ss')                  as DATE_uts
               
        from    t
        ) t
;        

ABC123  Humpty  2016-10-07 12:30:54 2   1
ABC123  Humpty  2016-10-07 12:30:54 1   0
ABC123  Humpty  2016-10-07 12:32:20 6   0

这也是我在Oracle上测试的结果

【讨论】:

  • 请看一下
  • 谢谢 Dudu 会做的,有什么解决方法把这个作为约会?
  • 我只是为你检查一些东西
  • 感谢 Dudu 指出问题。抱歉,当我输入问题时,逗号被遗漏了,但在查询中。关于您现在要尝试的查询,有一个问题,订单是否不需要 trunc,否则这将无法正确排序?
  • 我已经运行了代码,这给了我现在按日期顺序排列的结果,但 count1 结果仍然不正确,因为所有显示为 1.. 顺便说一句,感谢您的帮助,非常感谢您的时间。刚刚看到您对可识别日期格式的评论...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-05
  • 2012-05-04
  • 1970-01-01
  • 2017-07-13
  • 1970-01-01
相关资源
最近更新 更多