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

uyto3xhc  于 2021-06-26  发布在  Hive
关注(0)|答案(3)|浏览(450)

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

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\u iso8601\u timestamp是一个有效的日期函数。
有人能告诉我我做错了什么吗?

eqfvzcg8

eqfvzcg81#

在我最近的工作中遇到了类似的事情。aws的支持人员向我指出了达沃斯的解决方案,但它最终并没有对我的案例起作用。我的解决方案是:

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

这将转换 current_timestamp 哪个是 timestamp with time zonetimestamp 如果要验证字段的数据类型,可以使用:

select typeof(field_name) from db_name.vw_name

希望有帮助!

zvms9eto

zvms9eto2#

您可以在athena over timestamp data type(dt)中使用以下语法:

SELECT id,dt,dt AT TIME ZONE 'America/New_York' as dateTimeNY FROM Table
68de4m5k

68de4m5k3#

不幸的是,雅典娜并不完全支持所有的普雷斯托功能,它有局限性,技术上比普雷斯托落后几个版本。有人试图让雅典娜与aws glue metastore紧密集成,虽然它基于hive的metastore,但有一些不一致之处。我希望spark、hive、glue、athena、presto等都能使用同一个metastore,这会让生活更轻松,但回到你的问题:
这篇关于presto的旧teradata fork的文档提到了presto中时间戳的一些问题:
presto声明带/不带时区的时间戳的方法不是sql标准。在presto中,两者都使用单词timestamp来声明,例如timestamp“2003-12-10 10:32:02.1212”或timestamp“2003-12-10 10:32:02.1212 utc”。根据时间戳末尾是否包含时区,时间戳被确定为有时区或无时区。在其他系统中,时间戳被显式地声明为带时区的时间戳或不带时区的时间戳
雅典娜的普雷斯托版本确实支持这两种观点 timestamp 以及 timestamp with timezone 但是teradata文档中提到的这种怪癖不应该成为问题。真正的问题是雅典娜不支持带时区的时间戳。
您链接的presto文档显示该函数返回不支持的类型的值 timestamp with timezone ,因此需要将其转换为其他受支持的内容。这是一个疏忽,雅典娜允许函数和铸造到一个数据类型,然后不支持,希望这将得到补救,但现在你必须解决它。
你需要做的是使用 CAST() 函数,它将从 timestamp with time zone 进入 timestamp 不幸的是,您可能无法将字符串直接转换为时间戳,尽管这取决于字符串的格式。你也不能用你写作的方式 timestamp 在字符串之前例如不能做 timestamp '2018-01-01 15:00:00' 原因我将在下面解释。

from \u iso1601 \u 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错误[失败]:无效的\u转换\u参数:值不能转换为时间戳

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

注意,select部分是有效的,它表示它是一个 timestamp ,但由于某些内部不一致的原因,您无法创建视图,并且会出现错误。

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中的值时不需要。这是一个需要解决的问题。

这很管用耶

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"
)

相关问题