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

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (102)

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

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
)

它给了我以下错误:

您的查询具有以下错误:不支持的Hive类型:带时区的时间戳

但是当我自己运行查询时它工作正常,这里提到From_iso8601_timestamp 作为有效的日期函数。

谁能告诉我我做错了什么?

提问于
用户回答回答于

不幸的是,Athena并不完全支持所有Presto功能,技术上是Presto背后的几个版本。有一些尝试让Athena与AWS Glue Metastore紧密集成,而AWS Glue Metastore虽然基于Hive的Metastore有一些不一致的地方。我希望Spark,Hive,Glue,Athena,Presto等人能够使用相同的Metastore,它会让生活更轻松,但回到你的问题:

这篇关于Presto旧版teradata分支的文档提到了presto中的时间戳问题:

Presto用于/不用时区声明时间戳的方法不是sql标准。在Presto中,两者都使用TIMESTAMP一词声明,例如TIMESTAMP'2003-12-10 10:32:02.1212'或TIMESTAMP'2003-12-10 10:32:02.1212 UTC'。根据您是否在时间戳结束时包含时区,确定时间戳是否带有时区。在其他系统中,时间戳显式声明为TIMESTAMP WITH TIME ZONE或TIMESTAMP WITHOUT TIME ZONE

您链接的presto文档显示该函数返回该不受支持的类型的值timestamp with timezone,因此您需要将其转换为支持的其他内容。Athena允许函数和强制转换为不受支持的数据类型,这是非常不愉快的。

你需要做的是使用CAST()功能周围的函数调用,将类型从改变timestamp with time zonetimestamp

遗憾的是,您可能无法将字符串直接转换为时间戳,但这取决于字符串的格式。你也不能用timestamp在字符串之前使用你所写的铸造风格,例如timestamp '2018-01-01 15:00:00'由于我将在下面解释的原因无法做到。

from_iso1601_timestamp()函数返回的类型

SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT From_iso8601_timestamp('2018-01-01T15:00:00Z') as "real_date"
)

带时区的时间戳

以下不起作用

SELECT typeof("real_date") AS real_date_type
FROM
(
SELECT CAST('2018-01-01T15:00:00Z' AS timestamp) as "real_date"
)

SQL错误[FAILED]:INVALID_CAST_ARGUMENT:无法将值强制转换为时间戳

这种样式的Casting还返回时区的时间戳:(

请注意,这部分的SELECT部分​​有效,它表示它是a timestamp,但根据上面提到的Teradata页面上的信息,这样做实际上是别名timestamp with timezone,你会得到一个错误

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错误[FAILED]:无法初始化类com.facebook.presto.util.DateTimeZoneIndex

以下可以执行

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"
)
用户回答回答于

在最近我正在做的事情上有类似的东西。 AWS Support向我指出了达沃斯解决方案,但它并没有最终为我的案例工作。 最终由我工作的解决方案是:

创建或替换视图db_name.vw_name AS

选择

    from_unixtime(cast(to_unixtime(current_timestamp)AS bigint))as field_name

来自db_name.tbl_name

这会将current_timestamp的输出(时间戳与时区)转换为时间戳

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

从db_name.vw_name中选择typeof(field_name)

希望有所帮助!

所属标签

可能回答问题的人

  • HKC

    红客学院 · 创始人 (已认证)

    27 粉丝7 提问5 回答
  • 西风

    renzha.net · 站长 (已认证)

    9 粉丝1 提问3 回答
  • 螃蟹居

    1 粉丝0 提问2 回答
  • 富有想象力的人

    2 粉丝0 提问1 回答

扫码关注云+社区

领取腾讯云代金券