首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在Athena上转换为带有时区的时间戳失败

在Athena上转换为带有时区的时间戳失败
EN

Stack Overflow用户
提问于 2018-06-13 16:52:45
回答 3查看 28.9K关注 0票数 18

我正在尝试创建以下视图:

代码语言:javascript
复制
CREATE OR REPLACE VIEW view_events AS 
(
   SELECT
     "rank"() OVER (PARTITION BY "tb1"."innerid" ORDER BY "tb1"."date" ASC) "r"
   , "tb2"."opcode"
   , "tb1"."innerid"
   , "tb1"."date"
   , From_iso8601_timestamp(tb1.date) as "real_date"
   , "tb2"."eventtype"
   , "tb1"."fuelused"
   , "tb1"."mileage"
   , "tb1"."latitude"
   , "tb1"."longitude"
   FROM
     rt_message_header tb1
   , rt_messages tb2
   WHERE ((("tb1"."uuid" = "tb2"."header_uuid") AND ("tb2"."opcode" = '39')) AND ("tb2"."type" = 'event'))
   ORDER BY "tb1"."innerid" ASC, "tb1"."date" ASC
)

它给出了以下错误:

您的查询有以下错误:不支持的配置单元类型:带有时区的时间戳

但是,当我自己运行查询时,它工作得很好,并且From_iso8601_timestamp被提到为有效的日期函数here

有人能告诉我我哪里做错了吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-06-29 15:13:37

不幸的是,雅典娜并不完全支持所有的Presto功能,它有limitations,技术上比Presto落后几个版本。有一些尝试让雅典娜与AWS胶元存储紧密集成,虽然它基于蜂巢的元存储,但有一些不一致。我希望Spark,Hive,Glue,Athena,Presto等人可以使用相同的metastore,这会让生活变得更容易,但回到你的问题上:

这个document about an older teradata fork of Presto在presto中提到了一些关于时间戳的问题:

sql用于声明带/不带时区的时间戳的方法不是

标准。在Presto中,两者都是使用单词TIMESTAMP声明的,例如,TIMESTAMP '2003-12-10 10:32:02.1212‘或TIMESTAMP '2003-12-10 10:32:02.1212 UTC’。根据时间戳末尾是否包含时区,确定时间戳是带时区的还是不带时区的。在其它系统中,时间戳被显式声明为带时区的时间戳或不带时区的时间戳

雅典娜的派生版本Presto确实支持timestamptimestamp with timezone,但有teradata文档中提到的那个怪癖,这不应该是一个问题。真正的问题是Athena does not support timestamp with timezone

您链接的presto文档显示该函数返回一个不受支持的timestamp with timezone类型的值,因此您需要将其转换为其他受支持的类型。这是一个疏忽,雅典娜允许函数和类型转换为不受支持的数据类型,希望这将得到补救,但现在您必须解决这个问题。

您需要做的是在该函数调用周围使用CAST()函数,这会将类型从timestamp with time zone更改为timestamp

不幸的是,您可能不能将字符串直接转换为时间戳,尽管这取决于字符串的格式。你也不能使用在字符串之前写timestamp的类型,例如,由于我将在下面解释的原因,不能做timestamp '2018-01-01 15:00:00'

from_iso1601_timestamp()函数返回的类型

代码语言:javascript
复制
SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT From_iso8601_timestamp('2018-01-01T15:00:00Z') as "real_date"
)

带有时区的

时间戳

这不管用

代码语言:javascript
复制
SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT CAST('2018-01-01T15:00:00Z' AS timestamp) as "real_date"
)

SQL错误失败: INVALID_CAST_ARGUMENT:值不能转换为时间戳

这种类型的转换还会返回带有时区的时间戳:(

请注意,这段代码的SELECT部分是有效的,它表明它是一个timestamp,但是由于某些内部不一致的原因,您无法创建视图,并且会得到一个错误。

代码语言:javascript
复制
CREATE OR replace VIEW test 
AS 
SELECT typeof( "real_date" ) AS real_date_type
FROM
(
SELECT  timestamp '2018-01-01 15:00:00' as "real_date"
)

SQL错误失败:无法初始化类com.facebook.presto.util.DateTimeZoneIndex

不管出于什么原因,创建一个视图需要该java类,而解析select中的值却不需要,这是一个需要解决的bug。

这个不错。

代码语言:javascript
复制
CREATE OR REPLACE VIEW test
AS
SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT CAST(From_iso8601_timestamp('2018-01-01T15:00:00Z') AS timestamp) as "real_date"
)
票数 29
EN

Stack Overflow用户

发布于 2019-06-13 15:02:52

在Athena中,您可以在时间戳数据类型(Dt)上使用以下语法:

代码语言:javascript
复制
SELECT id,dt,dt AT TIME ZONE 'America/New_York' as dateTimeNY FROM Table
票数 5
EN

Stack Overflow用户

发布于 2019-03-05 04:16:06

在我最近正在做的事情上遇到了类似的事情。AWS支持将我引向了达沃斯解决方案,但它最终并不适用于我的情况。从我那里得到的解决方案是:

代码语言:javascript
复制
create or replace view db_name.vw_name AS
select
    from_unixtime(cast(to_unixtime(current_timestamp) AS bigint)) as field_name
from db_name.tbl_name

这会将timestamp with time zonecurrent_timestamp的输出转换为timestamp

如果要验证字段的数据类型,可以使用:

代码语言:javascript
复制
select typeof(field_name) from db_name.vw_name

希望这能有所帮助!

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50832977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档