如何在Presto(Athena)中将字符串转为时间戳?解决查询类型不匹配错误
解决Athena中字符串时间与Timestamp比较的报错问题
核心问题很明确:你的date字段是VARCHAR类型,但DATE_ADD和NOW()返回的是带时区的Timestamp类型,Athena不允许直接在不同类型的时间值之间做BETWEEN比较。同时你需要把ISO格式的字符串时间转换成标准Timestamp格式,下面是具体的解决步骤:
1. 字符串时间转Timestamp的方法
针对你的示例时间字符串'2018-03-27T00:20:00.855556Z',Athena提供两种实用的转换方式:
方式一:用parse_datetime精确解析(推荐)
可以指定精确的时间格式来解析字符串,避免格式识别错误:
parse_datetime(date, 'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z''')
如果需要去掉毫秒部分,转换成'2018-03-27 00:20:00'这种格式,结合date_trunc即可:
date_trunc('second', parse_datetime(date, 'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z'''))
方式二:直接CAST转换
如果你的字符串是标准ISO 8601格式,Athena可以自动识别,直接转换更简洁:
CAST(date AS timestamp)
2. 修改查询语句解决报错
把date字段转换成Timestamp后再进行范围比较,修改后的查询如下:
SELECT * FROM tb_name WHERE elb_status_code LIKE '5%%' AND parse_datetime(date, 'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z''') BETWEEN DATE_ADD('hour', -2, NOW()) AND NOW();
或者使用CAST的简化版本:
SELECT * FROM tb_name WHERE elb_status_code LIKE '5%%' AND CAST(date AS timestamp) BETWEEN DATE_ADD('hour', -2, NOW()) AND NOW();
3. 长期优化建议
如果这个表需要频繁做时间范围查询,建议修改date字段的元数据类型为Timestamp,这样后续查询不需要每次转换,效率更高:
ALTER TABLE vf_aws_metrices.tb_name ALTER COLUMN date SET DATA TYPE timestamp WITH (format = 'yyyy-MM-dd''T''HH:mm:ss.SSSSSS''Z''');
注意:执行这个语句前要确保S3中的实际数据格式和指定格式一致,否则会出现数据解析错误。
内容的提问来源于stack exchange,提问作者Harshit Agrawal




