Spark SQL和Hive在处理日期/时间上的差异

博主历时三年倾注大量心血创作的《大数据平台架构与原型实现:数据中台建设实战》一书已由知名IT图书品牌电子工业出版社博文视点出版发行,真诚推荐给每一位读者!点击《重磅推荐:建大数据平台太难了!给我发个工程原型吧!》了解图书详情,扫码进入京东手机购书页面!

在这里插入图片描述

 

 

注: 本文使用的环境是:Spark:2.2, Hive: 1.2.1

最近在编写一个SQL的过程中遇到了这样一个陷阱:为了便于工作,SQL的编写是通过一个SQL的IDE环境以Hive JDBC驱动的方式连接到HIVE上去执行的,SQL在HIVE上执行正常,有结果数据返回。但是SQL开发好在程序执行时通过Spark-SQL来运行的,SQL可以成功执行,没有报出任何语法错误,但是没有任何结果数据!在经过仔细查询后,发现问题出现在where条件中对理日期/时间字段的比较上。 以下where字句:

where creation_date >= start_time and creation_date < end_time ....

其中creation_date是date类型,start_time和end_time是timestamp类型。虽然是两种时间类型,但是确实是可以直接比较大小的,人们会默认的转换规则是:对于date类型,如果要与timestamp类型进行比较,会默认在时间部分上补齐"00:00:00.00000000", 但是如果在不显式地指定这种转换下,默认的两个类型间的比较结果如下:

  • 使用原始字面量进比较
SQL HIVE执行结果 SPARK-SQL执行结果
select ‘2019-01-01’ < ‘2019-01-01 00:00:00’; true true
select ‘2019-01-01’ = ‘2019-01-01 00:00:00’; false false
select ‘2019-01-01’ < ‘2019-01-01 00:00:00’; false false

date类型的’2019-01-01’一定是比timestamp类型的’2019-01-01 00:00:00’要。虽然这有些怪异,但在hive和spark-sql上这一比较是一致的

  • 强制类型转换后进行比较
SQL HIVE执行结果 SPARK-SQL执行结果
select cast(‘2019-01-01’ as date) < cast(‘2019-01-01 00:00:00’ as timestamp); false true
select cast(‘2019-01-01’ as date) = cast(‘2019-01-01 00:00:00’ as timestamp); true false
select cast(‘2019-01-01’ as date) > cast(‘2019-01-01 00:00:00’ as timestamp); false false

这比较让人更加费解,本质上对于’2019-01-01’和’2019-01-01 00:00:00’两个字面量的类型转换都是它们本来的类型,对于Spark-SQL来说,它保持了和前一个版本以纯字面量比较一致的结果,但Hive的比较结果发生了变化,变成了“默认的那种”结果,这是有问题的。如果我们再一步的比较’2019-01-01’和cast(‘2019-01-01’ as date),那么对于Hive的行为就更加难以理解了:

select '2019-01-01' = cast('2019-01-01' as date);  ->  hive: true, spark-sql: true

总之,Hive在处理date类型与timestamp类型的比较上是有问题的! 结果不符合人们的预期,所以最好的作法是将date类型转化为timestamp之后再进行比较! 像下面这样:

SQL HIVE执行结果 SPARK-SQL执行结果
select cast(‘2019-01-01’ as timestamp) < cast(‘2019-01-01 00:00:00’ as timestamp); false false
select cast(‘2019-01-01’ as timestamp) = cast(‘2019-01-01 00:00:00’ as timestamp); true true
select cast(‘2019-01-01’ as timestamp) > cast(‘2019-01-01 00:00:00’ as timestamp); false false
bluishglc CSDN认证博客专家 CSDN博客专家
耿立超,架构师,CSDN博客专家,14年IT系统开发和架构经验,对大数据、企业级应用架构、SaaS、分布式存储和领域驱动设计有丰富的实践经验。对Hadoop/Spark 生态系统有深入和广泛的研究,参与过Hadoop商业发行版的开发,目前负责企业数据中台的架构设计和开发工作,热衷函数式编程,著有《大数据平台架构与原型实现:数据中台建设实战》https://item.jd.com/12677623.html 一书。
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值