m6uのエンジニアっぽい日記

PHP利用開発やFuelPHP利用開発、PostgreSQL利用開発、Androidアプリ開発、CentOS7サーバー構築など、テクニカルでエンジニアっぽい内容の日記

PostgreSQL: 日数を求める

日数を求めるのに、日付と日付の引き算をします

 日付型どうしなら、引き算すると整数値が出てきます。

select cast('2016-12-01' as date) - cast('2016-11-01' as date) 

f:id:m6u:20170112113757p:plain
 タイムスタンプ型どうしなら、interval型で出てきます。

select cast('2016-12-01' as timestamp) - cast('2016-11-01' as timestamp) 

f:id:m6u:20170112113827p:plain
 interval型には数値と単位が融合していて便利な半面、単純に日数の数値だけほしいときに困ります。
 そんなときは、下記のように「extract(epoch from ~ )」を活用します。

select extract(epoch from (cast('2016-12-01' as timestamp) - cast('2016-11-01' as timestamp))) / (60 * 60 * 24) 

f:id:m6u:20170112114310p:plain
 interval型をepochで抽出すると秒数に変わるので、一日の秒数である「60 * 60 * 24」つまり「86400」で割れば良いとのことです。
 こちらのブログ記事を参考にしました。 ありがとうございます。
d.hatena.ne.jp

余談ですが、timestamp型どうしの日数を求めるときの注意点

select cast('2016-12-01 9:00:00' as timestamp) - cast('2016-11-01 15:00:00' as timestamp) 

f:id:m6u:20170112115214p:plain
 timestamp型の場合、時刻成分の影響で期待する日数が得られない場合があります。 この事例だと厳密には30日に達していないのですが、時刻成分を無視して日付単位で日数を得るには、「date_trunc('day', ~)」を活用します。

select date_trunc('day', cast('2016-12-01 9:00:00' as timestamp)) - date_trunc('day', cast('2016-11-01 15:00:00' as timestamp))

f:id:m6u:20170112115604p:plain