Postgresql

如何將日/夜指示器添加到時間戳列?

  • June 7, 2020

我使用一timestamp列來指示行是在白天還是晚上創建的。我的程式碼如下,但由於某種原因,我只得到“DAY”作為結果。我沒有正確格式化值嗎?

select record_id, rec_date,
      case when date_part('hour', rec_date) between 20 and 07 then 'Night'
           else 'Day' end as Indicator
from records;      

rec_date列是一個時間戳,我可以在其中看到諸如2019-11-20 21:34:02.000000- 應該得到一個'Night'指標的值。

SELECT record_id, rec_date
    , CASE WHEN rec_date::time <  '08:00' THEN 'Night'
           WHEN rec_date::time >= '20:00' THEN 'Night'
           ELSE 'Day' END AS indicator
FROM  records;

為什麼?

這是date-math而不是date-format的問題。您想正確有效地進行數學運算。“日”和“夜”的格式沒有問題。

McNets 已經對BETWEENBETWEEN SYMMETRIC. 但BETWEEN SYMMETRIC 20 AND 07最終還是會變得醜陋、緩慢和不正確

  1. SYMMETRIC只有在您不知道哪個會更大的情況下,參數化邊界才有意義。不是這樣,20而且07是常數。
  2. 天真地應用於您的案例,您會日夜顛倒,因為BETWEEN SYMMETRIC 20 AND 07最終被評估為BETWEEN 07 AND 20(只是更昂貴)。
  3. 好的,通過切換“白天”和“夜晚”輕鬆修復。但是現在,時間 20:** 和 07:** 將被標記為“Day”。BETWEEN,有或沒有SYMMETRIC,包括上限下限。這就是為什麼它幾乎總是與 timestamps 一起使用的錯誤工具。在這種特殊情況下,date_part()恰好在某種程度上解決了包含兩個邊界的內置問題。無論哪種方式,為了符合您的初衷,它必須是:
CASE WHEN date_part('hour', ts) BETWEEN '08' AND '19'  -- adjusted
    THEN 'Day' ELSE 'Night' END AS indicator
  1. 帶有表達式的查詢大約是我建議的date_part('hour', rec_date) BETWEEN SYMMETRIC 20 AND 07兩倍。較大的部分由於無意義,較小的部分由於功能比鑄件更昂貴。SYMMETRIC
  2. 建議的表達式比 devious 更不容易被誤解BETWEEN,因為它明確了包含哪些邊界。

旁白

我不會將時間戳列稱為“record_date”,因為date它是一種不同於timestamp. 更大的混亂可能性。

如果您的實際數據類型恰好是timestamptz(或者可能在任何情況下),您可能必須定義應該是“白天”還是“夜晚”。看:

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