PostgreSQL 的 date 加 INTERVAL 會變成 timestamp

date + integer 回傳 date,但 date + interval 回傳 timestamp。加完之後型態不一樣,拿去跟 date 欄位比對就會對不上。

SELECT DATE '2024-03-17' + 1;                  -- date      → 2024-03-18
SELECT DATE '2024-03-17' + INTERVAL '1 day';   -- timestamp → 2024-03-18 00:00:00

為什麼會咬人

join 或 where 條件寫成這樣時,左邊是 date、右邊被提升成 timestamp:

ON w1.recordDate = w2.recordDate + INTERVAL '1 day'   -- ❌ 型態不符
ON w1.recordDate = (w2.recordDate + INTERVAL '1 day')::date  -- ✅ 轉回來
ON w1.recordDate = w2.recordDate + 1                  -- ✅ 更乾淨

危險的是欄位本身是 timestamp 的時候不會報錯,而是安靜地比錯:timestamp 帶時分秒,= 某日 00:00:00 只會命中剛好整點那一筆。要比「同一天」得用 ::date 或範圍條件。

判準

  • 純日期運算:優先 + 整數,不繞 INTERVAL。
  • 需要 INTERVAL(月、小時等非固定天數)時,運算完立刻 ::date 收回來。
  • 這是 PostgreSQL 的型別規則,MySQL 走 DATE_ADD()/+ INTERVAL 1 DAY 是另一套,跨 DB 抄語法前先確認,見 DELETE 搭 JOIN 的寫法 MySQL 與 PostgreSQL 不相容。