PostgreSQLのdate_truncの使い方とユースケース

こんにちは!kossyです!




今回はRailsPostgreSQLを使ってSQLをベタ書きする際に使えるdate_truncのユースケースについてブログに残してみたいと思います。




環境
PostgreSQL 12系



公式ドキュメントを読む

まずは公式Docを読んでみます。

www.postgresql.jp

date_trunc関数は概念的に数値に対するtrunc関数と類似しています。

date_trunc(field, source [, time_zone ])

sourceは、データ型timestamp、timestamp with time zoneもしくはintervalの評価式です。
(date型とtime型の値はそれぞれ自動的にtimestampもしくはintervalにキャストされます。)
fieldは、入力値の値をどの精度で切り捨てるかを選択します。
同様に戻り値はtimestamp、timestamp with time zoneもしくはinterval型で、
指定した精度より下のすべてのフィールドがゼロに設定(日と月については1に設定)されます。

入力値がtimestamp with time zone型の値なら、特定の時間帯を考慮して切り捨てが行われます。
たとえば、日を切り捨てると値はその時間帯での真夜中になります。
デフォルトでは切り捨ては現在のTimeZoneの設定に従いますが、別の時間帯を指定することができるようにオプションのtime_zone引数が提供されています。

timestamp without time zoneあるいはintervalの入力を処理している間は時間帯は指定できません。 これらは額面通りの値で扱われます。

出典:
https://www.postgresql.jp/document/12/html/functions-datetime.html

日付に対する加工処理を行うことができる関数です。次の項で使用されるシチュエーションについて記述します。


シチュエーション

例えばRailsのApplicationRecordを継承したモデルのcreated_atを比較演算子にそのまま渡しても、
JSTUTCが時刻に含まれてしまって、正しく比較できないことがあります。

そんな時、date_truncを使えばうまく比較することができます。

self.created_at < date_trunc('day', self.started_at) + interval '1 day'

このように、date_trunc関数を使うことで、RailsActiveRecordでは記述できない痒いところにも手が届く実装が可能になります。



勉強になりました。