在同一個查詢中將日期和時間戳與時區與 now() 進行比較?
我有多個數據庫伺服器,我正在使用一個將過期列與
now()
. 問題是其中一個伺服器的過期列是 atimestamp 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 可以自動比較
date
和timestamp
(有或沒有時區)。如果一個是 adate
,它會timestamp
自動轉換為(0:0 小時)。錯誤消息講述了一個不同的故事。您實際上是在嘗試
date
使用無效語法輸入 a 。我最近寫了一個關於在 PostgreSQL 中處理帶或不帶時區的時間戳的詳細答案 - 如果這應該是問題:
事實證明,
expiration
是一text
列。您需要將其轉換為date
ortimestamp
(無論哪個適合您的需要)。如果格式有效:... 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()
轉換為文本 (
::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')