Hive/SparkSQL:如何将 Unix 时间戳转换为时间戳(不是字符串)?

Posted

技术标签:

【中文标题】Hive/SparkSQL:如何将 Unix 时间戳转换为时间戳(不是字符串)?【英文标题】:Hive/SparkSQL: How to convert a Unix timestamp into a timestamp (not string)? 【发布时间】:2017-10-21 23:15:21 【问题描述】:

我认为这很容易......

在 Hive/SparkSQL 中,如何将 unix 时间戳 [注 1] 转换为 timestamp 数据类型?

(注 1:即自 1970 年 1 月 1 日以来的秒数/毫秒数)

我以为from_unixtime() 会这样做,但它会返回一个字符串 而不是时间戳。下面的实验说明了这个问题

步骤 0:准备

select 
  from_unixtime(1508673584) as fut;

结果:

-----------------------
| fut                 |
| ------------------- |
| 2017-10-22 11:59:44 |
-----------------------

第一步:创建一个结果为from_unixtime()的表

create table test
select 
  from_unixtime(1508673584) as fut;

第2步:检查fut列的数据类型

describe test;

结果:

----------------------------------
| col_name | data_type | comment |
| -------- | --------- | ------- |
| fut      | string    | <null>  |
----------------------------------

我也试过了

select 
  from_utc_timestamp(1508618794*1000, 'EDT');

根据手册(链接here),这应该可以工作。因为它 声明:

将 UTC 中的时间戳*转换为给定的时区(从 Hive 0.8.0 开始)。 * 时间戳是一个原始类型,包括时间戳/日期, tinyint/smallint/int/bigint、float/double 和小数。分数 值被视为秒。整数值被视为 毫秒.. 例如 from_utc_timestamp(2592000.0,'PST'), from_utc_timestamp(2592000000,'PST') 和 from_utc_timestamp(timestamp '1970-01-30 16:00:00','PST') 都返回时间戳 1970-01-30 08:00:00

但是,我得到了一个错误

Error: org.apache.spark.sql.AnalysisException: 
  cannot resolve 'from_utc_timestamp((1508618794 * 1000), 'EDT')' 
  due to data type mismatch: 
  argument 1 requires timestamp type, 
  however, '(1508618794 * 1000)' is of int type.; line 2 pos 2;
'Project [unresolvedalias(from_utc_timestamp((1508618794 * 1000), EDT), None)]
+- OneRowRelation$

SQLState:  null
ErrorCode: 0    

【问题讨论】:

【参考方案1】:

(我在这里自己提供答案。)

答案是使用cast()。这适用于datetimestamp

select 
  from_unixtime(1508673584)                    as fut,
  cast(from_unixtime(1508673584) as date)      as futAsDate,
  cast(from_unixtime(1508673584) as timestamp) as futAsTimestamp;

结果:

------------------------------------------------------------
| fut                 | futAsDate  | futAsTimestamp        |
| ------------------- | ---------- | --------------------- |
| 2017-10-22 11:59:44 | 2017-10-22 | 2017-10-22 11:59:44.0 |
------------------------------------------------------------

数据类型验证

create table test2
select 
  from_unixtime(1508673584)                    as fut,
  cast(from_unixtime(1508673584) as date)      as futAsDate,
  cast(from_unixtime(1508673584) as timestamp) as futAsTimestamp;

然后

describe test2;  

结果:

----------------------------------------
| col_name       | data_type | comment |
| -------------- | --------- | ------- |
| fut            | string    | <null>  |
| futAsDate      | date      | <null>  |
| futAsTimestamp | timestamp | <null>  |
----------------------------------------

【讨论】:

【参考方案2】:

创建表测试 AS select cast(from_unixtime(1508673584) as timestamp) as fut;

【讨论】:

以上是关于Hive/SparkSQL:如何将 Unix 时间戳转换为时间戳(不是字符串)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Hive/Spark SQL 中使用窗口函数删除重叠

Java采用JDBC的方式连接Hive(SparkSQL)

Spark SQL 到底怎么搭建起来

spark hive区别

Hive/Spark SQL 查询方法

60分钟内从零起步驾驭Hive实战