2010-12-11 17 views
0

私のデータベースでは、すべてのcreatedタイムスタンプが同じ年を持つことが必要な日時操作を行う必要があります。PostgreSQLでのタイムスタンプの操作 - 時間/時間帯の問題

select created,cast (created - 
    to_timestamp(''||date_part('year', created), 'YYYY') + 
    timestamp '2010-01-01' as timestamp without time zone) 
    from table where created is not null limit 10; 

...しかし、結果は部分的にしか満足です:私はこのクエリを試してみました

 created  |  timestamp  
---------------------+--------------------- 
2010-08-29 12:44:05 | 2010-08-29 11:44:05 
2007-06-21 13:49:22 | 2010-06-21 12:49:22 
2007-06-21 15:02:33 | 2010-06-21 14:02:33 
2007-06-21 15:05:26 | 2010-06-21 14:05:26 
1999-09-30 13:00:00 | 2010-09-30 12:00:00 
1997-06-07 13:00:00 | 2010-06-07 12:00:00 
2010-06-15 20:51:01 | 2010-06-15 19:51:01 
2006-08-26 15:33:02 | 2010-08-26 14:33:02 
2009-12-15 11:07:06 | 2010-12-15 11:07:06 
1997-06-28 13:00:00 | 2010-06-28 12:00:00 
(10 rows) 

あなたが見ることができるように、すべてのタイムスタンプは-1元created値と比較する時間。さらに奇妙なのは、最後の1つ前のもの(2010-12-15 11:07:06)ではないということです。

createdカラムは、timestamp without time zoneタイプです。

何が間違っていたのでしょうか?

答えて

1

SQLの問題は、別の年の日付に日付を変換しないことです。それは作成された2010年1月1日のデルタを計算し、それを日付に変換します。だからあなたは実際に年の部分を削除するのではなく、どれくらい前にそれを計算していますか?

この問題にアプローチするもう1つの方法があります。それはちょうど年を置き換え、日付の残りの部分はそのままにしておきます。

SELECT TO_TIMESTAMP('2010-' || CAST(EXTRACT(MONTH FROM created) AS VARCHAR) || '-' || CAST(EXTRACT(DAY FROM created) AS VARCHAR) || ' ' || CAST(EXTRACT(HOUR FROM created) AS VARCHAR) ||':'||CAST(EXTRACT(MINUTE FROM created) AS VARCHAR) ||':'|| CAST(EXTRACT(SECONDS FROM created) AS VARCHAR), 'YYYY-MM-dd HH24:MI:SS') AS timestamp FROM table; 

これは部分文字列でも実行できます。 TO_TIMESTAMP()は2010-02-29を2010年3月1日にキャストしますので、安全に使用できます。このサブソリューションJMZが記載されて

1

 
select to_timestamp('2010'||substring(to_char(created, 'yyyy-mm-dd hh24:mi:ss.ms'), 5), 'yyyy-mm-dd hh24:mi:ss.ms') 
0

みんなありがとうを、両方JMZとa_horse_with_no_nameソリューションが正常に動作します。

私も解決しました。問題は、timestamp with time zoneを返すto_timestampであり、私はtimestamp without time zoneを期待していました。型キャストを追加するだけで十分でした:

select created,cast (created-to_timestamp(''|| 
    date_part('year', created), 'YYYY')::timestamp without time zone + 
    timestamp '2010-01-01' as timestamp without time zone) 
    from table;