web-dev-qa-db-ja.com

PostgreSQLのタイムスタンプの時間差

PostgreSQLに相当するTIMESTAMPDIFF()がありますか?

2つのタイムスタンプを減算してpostgresql INTERVALを取得できることを知っています。 INTで表される時間単位の2つのタイムスタンプの差が欲しいだけです。

私はこれをMySQLで次のように行うことができます:

TIMESTAMPDIFF(HOUR, links.created, NOW())

整数として表される時間単位の2つのタイムスタンプの差が必要なだけです。

解決策は私のために働く:

SELECT "links_link"."created",
"links_link"."title",
(EXTRACT(Epoch FROM current_timestamp - "links_link"."created")/3600)::Integer AS "age" 
FROM "links_link"
52
TheLizardKing

最初に現れるもの

EXTRACT(Epoch FROM current_timestamp-somedate)/3600

きれいではないかもしれませんが、道路のブロックを解除します。間隔による間隔の除算が定義されている場合、きれいになる可能性があります。

編集:ゼロより大きくしたい場合は、absまたはgreatest(...、0)を使用します。あなたの意図に合ったもの。

Edit ++ageを使用しなかった理由は、ドキュメントを引用するために、ageが単一の引数であるためです。current_dateから減算(at真夜中)。つまり、真夜中に実行しない限り、正確な「年齢」は得られません。今は午前1時近くです。

select age(current_timestamp);
       age        
------------------
 -00:52:40.826309
(1 row)

タイムスタンプがpostgresqlの日付より大きいフィールドを取得します:

SELECT * from yourtable 
WHERE your_timestamp_field > to_date('05 Dec 2000', 'DD Mon YYYY');

postgresqlのタイムスタンプから分を引く:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 minutes'

postgresqlのタイムスタンプから時間を引く:

SELECT * from yourtable 
WHERE your_timestamp_field > current_timestamp - interval '5 hours'
26
Eric Leschinski

Michael Krelinの答えは、まれな状況では間違っている可能性があるため、近いというのは完全に安全ではありません。問題は、PostgreSQLの間隔が夏時間のようなものに関してコンテキストを持たないことです。間隔は、内部的に月、日、秒として物事を保存します。この場合、月は問題になりません。2つのタイムスタンプを引くには日と秒を使用するだけですが、「日」が問題になる可能性があります。

減算に夏時間の切り替えが含まれる場合、特定の日はそれぞれ23時間または25時間と見なされます。間隔はそれを考慮に入れます。これは、シンボリックな意味で経過した日数を知るのに役立ちますが、実際の経過時間の間違った数を与えます。間隔のエポックは、すべての日数に24時間を掛けるだけです。

たとえば、完全な「短い」日が過ぎて翌日の追加の時間が経過した場合、間隔は1日と1時間として記録されます。 Epoch/3600に変換されるのは25時間です。しかし、実際には23時間+ 1時間は合計24時間でなければなりません。

したがって、より安全な方法は次のとおりです。

(EXTRACT(Epoch FROM current_timestamp) - EXTRACT(Epoch FROM somedate))/3600

Michaelがフォローアップコメントで述べたように、floor()またはround()を使用して結果を整数値として取得することもできます。

14
ShawnFumo

タイムスタンプだけでなく間隔でも「抽出」または「日付部分」関数を使用できますが、それはあなたが望むことをするとは思いません。たとえば、「2日、3時間」の間隔で3を返します。ただし、必要な時間要素として「Epoch」を指定すると、間隔を秒数に変換できます。extract(Epoch from '2 days, 3 hours'::interval)は183600を返します(その後、3600で割って秒を時間に変換します)。

したがって、これをすべてまとめると、基本的にマイケルの答えが得られます:extract(Epoch from timestamp1 - timestamp2)/3600。どのタイムスタンプがどのタイムスタンプに先行するかは気にしないようですので、おそらくそれをabsでラップしたいでしょう:

SELECT abs(extract(Epoch from timestamp1 - timestamp2)/3600)
6
araqnid

postgresqlはタイムスタンプ間の秒数の差を取得

SELECT (
    (extract (Epoch from (
        '2012-01-01 18:25:00'::timestamp - '2012-01-01 18:25:02'::timestamp
                         )
             )
    )
)::integer

印刷するもの:

-2

タイムスタンプは2秒離れているためです。数を取得し、60で割って分を取得し、60で再び割って時間を取得します。

3
Eric Leschinski

データベース機能を利用したい多くの開発者にとって、これはおかしく聞こえるかもしれませんが、

しかし、日付関数を比較するPHPでmysqlとpostgrsqlのアプリケーションを考え、作成し、バグ修正した徹底的な問題の後、私は結論を出しました、それは最も簡単な方法、SQLの頭痛が少ない最も簡単な方法は利用しないことですそれらのいずれかの。

どうして? PHPのようなミドルウェア言語で開発している場合、PHPはこれらの機能をすべて備えており、整数を比較するためにアプリケーションodeに実装しやすい。PostgreSQLのタイムスタンプはNOT == UNIX TIMESTAMP MySQLのUNIX TIMESTAMPはPostgresQLやOracleのタイムスタンプではありません。データベースのタイムスタンプを使用すると移植が難しくなります。

したがって、1970年1月1日の午前0時からの秒数として、タイムスタンプではなく整数を使用してください。データベースのタイムスタンプを気にしないでください。 、gmdate()を使用し、タイムゾーンの問題を回避するためにすべてをgmt時間として保存します。

他のデータから日を検索、ソート、比較する必要がある場合、アプリケーション内の月、年、曜日、または何か、およびtime_day、time_hour、time_seconds。などのINTEGERデータ型検索するインデックスを作成すると、データベースがよりスムーズでポータブルになります。ほとんどの場合、1つのフィールドを使用できます:INTEGER time_created NOT NULL

(データベース行のより多くのフィールドは、私が見つけたこのソリューションの唯一の欠点であり、それは頭痛やコーヒーのカップを引き起こしません:)

phpの日付関数は日付を比較するのに優れていますが、mysqlまたはpostgresqlでは日付を比較しますか? nah ..整数のSQL比較を使用する

挿入関数でCURRENT_TIMESTAMPを使用する方が簡単な場合があることを認識しています。ハ!だまされてはいけません。

できませんDELETE FROM SESSION_TABLE WHERE time-initialized < '2 days' time-intitializedがpostgresqlタイムスタンプの場合。でもできること:

DELETE FROM SESSION_TABLE WHERE time_initialized < '$yesterday'

PHPで$ yesterdayを、昨日が1970年以降の秒の整数として設定している限り。

これは、postgresqlのselectステートメントでタイムスタンプを比較するよりも、セッションレコードのハウスキーピングが簡単です。

SELECT age()、SELECT extract()、およびasbtimeは、それ自体が頭痛の種です。これは私の意見です。

あなたは追加、減算、<、>をすべてPHP日付オブジェクトで行うことができます

_peter_sysko U4EA Networks、Inc.

2
Peter Sysko

extract(hour from age(now(),links.created))は、時間の差をフロア単位でカウントします。

1
Danix D5