我最近研究了一个数据库,其中日期和时间变量以 VARCHAR 类型的文本存储为多种不同格式(不要问...),并且必须将其转换为 TIMESTAMP 类型。由于 Redshift 没有这个TO_TIMESTAMP()
功能,所以我使用了 Yiyu Jia 在他的 [blog][1] 上提出的技巧。简而言之,诀窍是
- 使用 TO_DATE() 获取转换的日期
- 将输入文本的时间部分附加到上面
- 将结果字符串转换为 TIMESTAMP
例如,这是处理名为 myDate 的字段的代码段,其中日期采用以下任一格式
- “2013 年 2 月 8 日晚上 10:06”
- “25/09/2007 16:21:00”
它相当重,但有效。正则表达式测试用于测试日期是否对应于给定行上处理的格式。(仅在处理多种可能的格式时才需要)
“Feb 0 2013”的情况有点复杂,因为我在将文本提交给 TO_DATE() 之前删除了文本的时间部分,并且因为使用了另一个正则表达式来提取附加的时间部分(与用于相同目的的更简单的 SUBSTRING() 相反,在另一种情况下)。
... ,
CASE
-- Special date indicating "date not available": replaced by NULL
WHEN myDate = '31/12/9999 23:59:59' OR myDate = 'Dec 31 9999 11:59PM' THEN NULL
-- 'Feb 8 2013 10:06PM' case
WHEN myDate ~ '^[JFMASOND][a-z]{2}' THEN
CAST(TO_DATE(REGEXP_REPLACE(myDate , '\\s[0-9]{1,2}:[0-9]{2}[AP]M$', ''), 'Mon FMDD YYYY') || REGEXP_REPLACE(myDate , '[JFMASOND][a-z]{2}\\s+[0-9]{1,2}\\s+[0-9]{4}\\s+', ' ') AS TIMESTAMP)
-- '25/09/2007 16:21:00' case
WHEN myDate ~ '^[0-9]{2}/[0-9]{2}/[0-9]{4} ' THEN
CAST(TO_DATE(myDate , 'DD/MM/YYYY HH24:MI:SS') || SUBSTRING(myDate FROM 11) AS TIMESTAMP)
ELSE NULL
END AS MyNiceTimeStamp,
...
[1]: http://yiyujia.blogspot.com/2014/04/redshift-convert-integer-to-timestamp.html