Postgresql

在同一個查詢中將日期和時間戳與時區與 now() 進行比較?

  • August 10, 2016

我有多個數據庫伺服器,我正在使用一個將過期列與now(). 問題是其中一個伺服器的過期列是 a timestamp with time zone,其餘的都是簡單的date。我無法更改此設置,因為我沒有管理員訪問權限,實際上我只是在查詢視圖。Postgres 對我來說相當新,所以我不太了解日期和時間如何相互配合。

當我嘗試timestamp with time zone通過強制轉換timestamp為 a來查詢伺服器時date

...
WHERE
   (
       status_code = '30000'
       OR status_code = '30005'
   )
AND CAST(expiration AS DATE) > now()

expiration它可以工作,但是在已經date失敗的伺服器上使用相同的查詢:

$$ Err $$錯誤:日期類型的輸入語法無效:“無結束日期”

任何幫助將不勝感激,我真的不想硬編碼這個數據庫伺服器的異常。

永遠不會失敗(我簡化了一點):

WHERE status_code IN ('30000','30005')
AND   expiration > now() 

PostgreSQL 可以自動比較datetimestamp(有或沒有時區)。如果一個是 a date,它會timestamp自動轉換為(0:0 小時)。

錯誤消息講述了一個不同的故事。您實際上是在嘗試date使用無效語法輸入 a 。

我最近寫了一個關於在 PostgreSQL 中處理帶或不帶時區的時間戳的詳細答案 - 如果這應該是問題:


事實證明,expiration是一text列。您需要將其轉換為dateor timestamp(無論哪個適合您的需要)。如果格式有效:

...
AND   expiration::timestamptz > now() 

如果您在該文本列中有無效字元串,例如“無結束日期”,則需要清理源或在CASE構造中特別處理這些字元串:

...
AND   CASE WHEN expiration::text = 'No End Date' THEN 'infinity'::timestamp
          WHEN expiration::text = 'foo' THEN '-infinity'::timestamp
          ELSE expiration::timestamp
     END > now()

關於特殊值的手冊infinity

轉換為文本 ( ::text) 與 , 是多餘的text,但也使表達式與date/timestamp值一起工作。

如果時間戳文字的格式可能不明確,請使用to_date()orto_timestamp()並明確定義格式:

to_date('07/08/2013', 'DD/MM/YYYY')

如果應該是另一個時區的本地時間戳,請使用該AT TIME ZONE構造:expiration

expiration::timestamp AT TIME ZONE 'UTC' -- desired time zone here

如果expiration格式不明確/非標準,請使用to_timestamp()

to_timestamp(expiration::text, 'yyyy-mm-dd')

引用自:https://dba.stackexchange.com/questions/16036