Amazon RedshiftでTO_TIMESTAMP関数を使いたい場合の対応方法

2016.09.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

以前はサポートされていなかったのですが現在はサポートされています。 TO_TIMESTAMP 関数 - Amazon Redshift

Redshiftには文字列からDATE型に変換するTO_DATE関数はありますが、文字列からTIMESTAMP型に変換するTO_TIMESTAMP関数がありません。使いたい場合は以下のどちらの対応をすることになります

UDFを使う方法

以下のUDFで文字列からTIMESTAMP型へ変換できます。TO_DATEと同じように第1引数に日付の文字列、第2引数にフォーマットを指定します。 フォーマットに関してはYYYY(年)、MM(月)、DD(日)、HH24(0~23時)、HH(午前/午後0~11時)、MI(分)、SS(秒)が使えます。 TO_DATE関数と同じように使え、見た目もいいですがパフォーマンスは以下のCASTの方法の方がいいです。 パフォーマンスに問題がなければこちらでもいいかと思います。

CREATE OR REPLACE FUNCTION f_to_timestamp(text VARCHAR, template VARCHAR)
    RETURNS TIMESTAMP
    STABLE AS $$
    from datetime import datetime
    if text is None or template is None: return None
    template_format_convert_table = [
        ["YYYY","%Y"], ["MM","%m"], ["DD","%d"], ["HH24","%H"],
        ["HH","%I"], ["MI","%M"], ["SS","%S"],
    ]
    t = template.upper()
    for (base, new) in template_format_convert_table: t = t.replace(base, new)
    return datetime.strptime(text, t)
    $$ LANGUAGE plpythonu;
    
select f_to_timestamp('2016/09/20 12:34:56', 'YYYY/MM/DD HH24:MI:SS');

CASTする方法

ちょっと面倒な方法ですが、SUBSTRINGで文字列を日付と時間に分割してから、スペースを間に入れて結合した後にCASTします。 パフォーマンスはこちらの方がいいのでお勧めです。

SELECT
    (SUBSTRING(SAMPLE_DATE,1,8) || ' ' || SUBSTRING(SAMPLE_DATE,9,6))::TIMESTAMP
FROM
    (SELECT '20160913123456'::text SAMPLE_DATE);