Hive中TRUNC和TO_DATE之间有什么区别

mow*_*n10 4 sql oracle hadoop

嗨我试图找出使用TRUNC和TO_DATE之间的区别在于Hive.

目前在oracle中,我针对以下数据编写了以下case语句:

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
Run Code Online (Sandbox Code Playgroud)

这给了我结果:

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
Run Code Online (Sandbox Code Playgroud)

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

Error while compiling statement: FAILED: SemanticException Failed to breakup Windowing invocations into Groups. At least 1 group must only depend on input columns.
Run Code Online (Sandbox Code Playgroud)

所以我将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
Run Code Online (Sandbox Code Playgroud)

这给了我结果:

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
Run Code Online (Sandbox Code Playgroud)

这与我在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
Run Code Online (Sandbox Code Playgroud)

Dav*_*itz 8

1

Hive运算符和用户定义函数(UDF)

至今

返回时间戳字符串的日期部分(pre-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类型.


TRUNC

返回截断为格式指定单位的日期(从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. Trunc 在Hive中必须使用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
Run Code Online (Sandbox Code Playgroud)

和整个查询:

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
;        
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)

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