2つの日付から経過月数を求めたい場合、Oracle には MONTHS_BETWEEN という便利なファンクションが用意されているのだけど、あいにく PostgreSQL にそういったものは無い。
「こんなもの、きっと誰かが考えてくれているだろう」と検索したら、やっぱりあった。
CREATE FUNCTION MONTHS_BETWEEN(DATE,DATE) RETURNS NUMERIC AS 'SELECT to_number((date($1)-date($2)), ''999999999'')/31 ' LANGUAGE 'sql';
記事では上記のように関数定義しているのだけど、このように常に 31 で除算すると、2008/3/21 と 2008/1/4 の差がおよそ 2.48 となる。切り捨てて2ヵ月間と見るか、切り上げて3ヵ月間と見るか、四捨五入して2ヵ月間と見るか。四捨五入するならば、実際は2ヵ月17日の差なので、「3ヶ月間」とする方が、みんなの求めるものに近いと思う。
どうするか。
日付の差を操作する場合は、age関数を使いましょう。
-- 切捨する場合 SELECT extract(month FROM age(date1,date2)); -- 切上する場合 SELECT extract(month FROM age(date1,date2) + interval '@ 1 month'); -- 四捨五入(15日以前は切捨、16日以降は切上) SELECT extract(month FROM age(date1 + interval '@ 0.5 month',date2);
実際の現場では、4/10と5/10という2つの日付について、1ヵ月とみなす場合もあろうし、2ヵ月としたいケースもあるんじゃないかと思います。その辺は、上記参考に柔軟にイジイジすると良いと思います。