一直在使用dataworks,很容易将dataworks中的SQL混同于hiveSQL,其实两者还是不一样的,包括一些函数的用法,尽管函数名称一致,但是参数的用法,以及参数都不一致。在这里想要讲一下关于日期转换的一个事情,尽管很小,但是平时自己也遇到过,也走过一些弯路,想着记录下来,以备查询。
业务中会出现类似的情况
2023.12.1
2023年7月15
20231209 12:35:29
这种不标准的时间格式有的时候会很头疼。在dataworks中,该情况只能通过“迂回”的方式进行处理,我们来看下其分别的处理方式
2023.12.1
select to_date(concat(SPLIT("2023.12.1","[.]")[0],lpad(SPLIT("2023.12.1","[.]")[1],2,'0'),lpad(SPLIT("2023.12.1","[.]")[2],2,'0')),'yyyymmdd')
# 结果
_c0
2023-12-01 00:00:00
其余几条逻辑都是相似的。稍微解释一下,先通过split将非规范的日期的日月日分开,然后使用lpad来组合成标准的日期格式,这里有一点特别需要注意的,在dataworks中,对于日期中的月份的标准使用 mm或者MM均可,这跟hive是有差别的,即在dataworks中日期的标准格式为:yyyymmddhhmiss,而在hiveSQL中,日期的标准格式为:yyyyMMddHHmmss,可以看到在月份和分钟的书写上要求是不一致的。
另外再介绍一个函数,unix_timestamp,在dataworks中必须要是标准的日期或者日期时间或者时间戳或者相应的时间类字符串,并且只允许输入一个参数;在hive中,该函数可以输入两个参数,第一个参数如果与上述的一致,那么其可以直接解析,如果第一个参数是不规则的时间格式,那么通过第二个参数对其进行解析,例如:
select from_unixtime(unix_timestamp('20231209 12:35:29','yyyyMMdd HH:mm:ss'))
这样即可对字符串转化为时间戳,再转化为datetime类型。
那么如此,是否可以在dataworks中使用这种hive的这种语法呢?答案是“可以”。在你要书写的hivesql之前,写上如下的set语句:
set odps.sql.hive.compatible=true;
这样,dataworks即兼容了hive的语法规则,那么我们上述的例子,可以直接通过hive语法来实现
# 2023年7月15
set odps.sql.hive.compatible=true;
select from_unixtime(unix_timestamp('2023年7月15','yyyy年M月dd'))
# 结果
_c0
2023-07-15 00:00:00
以上!