在PostgreSQL中将表示时间戳的字符串转换为实际时间戳?

7
在PostgreSQL中,我使用to_timestamp()string转换为timestamp:
select * from ms_secondaryhealthcarearea
where to_timestamp((COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') 
    > to_timestamp('20121128191843','YYYYMMDDHH24MISS')

但我遇到了这个错误:
ERROR:  syntax error at end of input
LINE 1: ...H24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')
                                                                       ^
********** Error **********

ERROR: syntax error at end of input
SQL state: 42601
Character: 176

为什么?如何将一个字符串转换为时间戳

4个回答

8
一次多余的开括号。请尝试这样做:
select * 
from ms_secondaryhealthcarearea 
where to_timestamp(COALESCE(update_datetime, '19900101010101'),'YYYYMMDDHH24MISS') >to_timestamp('20121128191843','YYYYMMDDHH24MISS')

您在 to_timestamp 中有两个开放括号:

where to_timestamp((COA.. -- <-- the second one  is not needed!

6

@ppeterka指出了语法错误。

更紧迫的问题是:为什么一开始就要将时间戳数据存储为字符串?如果您的情况允许,考虑将该列转换为其正确的类型:

ALTER TABLE ms_secondaryhealthcarearea
ALTER COLUMN update_datetime TYPE timestamp
USING to_timestamp(update_datetime,'YYYYMMDDHH24MISS');

或者根据您的需求使用timestamptz


我甚至没有意识到整个故事背后隐藏着这个丑陋的问题 - 看似只是一个简单的语法问题。将日期存储为任何类型的字符串绝对是不可取的... - ppeterka

1
另一种将字符串转换为PostgreSql时间戳类型的方法如上所述。
SELECT to_timestamp('23-11-1986 06:30:00', 'DD-MM-YYYY hh24:mi:ss')::timestamp without time zone;

0

我有和标题所描述的一样的需求。如何将一个Epoch时间戳转换为真正的时间戳。在我的情况下,我从一个JSON对象中提取了一个时间戳作为文本,带有毫秒。

'1528446110978' (GMT: 2018年6月8日 星期五 上午8:21:50.978)

这是我尝试过的方法。只有后者(ts_ok_with_ms)完全正确。

SELECT
  data->>'expiration' AS expiration,
  pg_typeof(data->>'expiration'),
  -- to_timestamp(data->>'expiration'), < ERROR: function to_timestamp(text) does not exist
  to_timestamp(
    (data->>'expiration')::int8
  ) AS ts_wrong,
  to_timestamp(
    LEFT(
      data->>'expiration',
      10
    )::int8
  ) AS ts_ok,
  to_timestamp(
    LEFT(
      data->>'expiration',
      10
    )::int8
  ) + (
    CASE
      WHEN LENGTH(data->>'expiration') = 13
      THEN RIGHT(data->>'expiration', 3) ELSE '0'
    END||' ms')::interval AS ts_ok_with_ms
FROM (
  SELECT '{"expiration": 1528446110978}'::json AS data
) dummy

这是返回的(转置后的)记录:
expiration    1528446110978
pg_typeof     text
ts_wrong      50404-07-12 12:09:37.999872+00
ts_ok         2018-06-08 08:21:50+00
ts_ok_with_ms 2018-06-08 08:21:50.978+00

我相信我忽略了一个更简单的方法,可以从JSON对象中的时间戳字符串获取实际的毫秒级时间戳(ts_ok_with_ms),但我仍然希望这能有所帮助。

更新:以下是一个方便使用的函数。

CREATE OR REPLACE FUNCTION data.timestamp_from_text(ts text)
RETURNS timestamptz
LANGUAGE SQL AS
$$
  SELECT to_timestamp(LEFT(ts, 10)::int8) +
  (
    CASE
      WHEN LENGTH(ts) = 13
      THEN RIGHT(ts, 3) ELSE '0'
    END||' ms'
  )::interval
$$;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接