如何将epoch转换为datetime redshift?

时间:2016-10-02 08:59:24

标签: datetime amazon-redshift epoch

我在dbeaver工作。我有一张桌子x。

表x有一列“timestamp”

1464800406459 
1464800400452 
1464800414056 
1464800422854 
1464800411797

我想要的结果:

Wed, 01 Jun 2016 17:00:06.459 GMT
Wed, 01 Jun 2016 17:00:00.452 GMT
Wed, 01 Jun 2016 17:00:14.056 GMT
Wed, 01 Jun 2016 17:00:22.854 GMT 
Wed, 01 Jun 2016 17:00:11.797 GMT 

我尝试了红移查询

SELECT FROM_UNIXTIME(x.timestamp) as x_date_time 
FROM x

但没有用。

发生错误:

  

无效操作:函数from_unixtime(字符变化)不存在

我也试过

SELECT DATE_FORMAT(x.timestamp, '%d/%m/%Y') as x_date 
FROM x

发生错误:

  

无效操作:函数date_format(字符变化,“未知”)不存在

语法有问题吗?或者还有另一种方法可以转换为人类可读的日期和时间吗?

提前致谢

5 个答案:

答案 0 :(得分:45)

Redshift没有from_unixtime()函数。您需要使用以下sql查询来获取时间戳。它只是将纪元添加到纪元,并作为时间戳返回。

select timestamp 'epoch' + your_timestamp_column * interval '1 second' AS your_column_alias
from your_table

答案 1 :(得分:13)

最简单的解决方案是创建from_unixtime()函数:

CREATE OR REPLACE FUNCTION from_unixtime(epoch BIGINT)
  RETURNS TIMESTAMP  AS
'import datetime

return datetime.datetime.fromtimestamp(epoch)
'
LANGUAGE plpythonu IMMUTABLE;

有关详细信息,请参阅Redshift documentation on UDF

答案 2 :(得分:12)

UDF会很慢。检查3个解决方案和1k行的执行时间。

最慢的 -

-- using UDF from one of the answers
SELECT from_unixtime(column_with_time_in_ms/ 1000)
FROM table_name LIMIT 1000;

执行时间00:00:02.348062s

第二好 -

SELECT date_add('ms',column_with_time_in_ms,'1970-01-01')
FROM table_name LIMIT 1000;

执行时间00:00:01.112831s

最快 -

SELECT TIMESTAMP 'epoch' + column_with_time_in_ms/1000 *INTERVAL '1 second'
FROM table_name LIMIT 1000;

执行时间00:00:00.095102s

stl_query -

计算的执行时间
SELECT *
       ,endtime - starttime
FROM stl_query
WHERE querytxt ilike('%table_name%limit%')
ORDER BY starttime DESC;

答案 3 :(得分:0)

为快速参考,这是上面在Python中显示的from_unixtime函数的SQL UDF实现。我尚未测试性能,但我想它会与普通的SQL版本相似。不过,编写起来要容易得多。

注意:这将计算从纪元开始的

CREATE FUNCTION from_unixtime (BIGINT)
  RETURNS TIMESTAMP WITHOUT TIME ZONE
IMMUTABLE
as $$
  SELECT TIMESTAMP 'epoch' + $1 / 1000 * interval '1 second'
$$ LANGUAGE sql;

答案 4 :(得分:0)

我这样使用它

CAST(DATEADD(S, CONVERT(int,LEFT(column_name, 10)), '1970-01-01')as timestamp) as column_name

SELECT 
    ,task_id 
    ,CAST(DATEADD(S, CONVERT(int,LEFT(SLA, 10)), '1970-01-01')as timestamp) as SLA
FROM my_schema.my_task_table ;