- カテゴリ:
MONTHS_BETWEEN¶
2つのDATEまたはTIMESTAMP値の間の月数を返します。
たとえば、 MONTHS_BETWEEN('2020-02-01'::DATE, '2020-01-01'::DATE)
は1.0を返します。
- こちらもご参照ください:
構文¶
MONTHS_BETWEEN( <date_expr1> , <date_expr2> )
引数¶
date_expr1
元の日付。
date_expr2
差し引く日付。
戻り値¶
2つの日付の間の月数を表すFLOAT。
数値は以下のように計算されます。
FLOATの整数部分は、入力値の年と月の部分を使用して計算されます。
ほとんどの場合、小数部分は入力値の日と時間の部分を使用して計算されます。(月の割合を計算するとき、関数は各月を31日と見なします。)
ただし、2つの例外があります。
月の日が同じである場合(例:2月28日と3月28日)、 入力値の一方または両方がタイムスタンプであり、時刻が異なっていても 、小数部分はゼロです。
月の日が両方とも月の最後の日である場合(たとえば、2月28日と3月31日)、 月の日が同じでなくても、 小数部分はゼロです。
たとえば、この関数は、次の日付/タイムスタンプのペアのそれぞれが正確に1.0か月離れていると見なします。
日付/タイムスタンプ1
日付/タイムスタンプ2
注意
2019-03-01 02:00:00
2019-02-01 13:00:00
各月の同じ日。
2019-03-28
2019-02-28
各月の同じ日。
2019-03-31
2019-02-28
各月の最終日。
2019-03-31 01:00:00
2019-02-28 13:00:00
各月の最終日。
使用上の注意¶
日付(またはタイムスタンプ)d1がd2よりも前の時点を表す場合、
MONTHS_BETWEEN(d1, d2)
は負の値を返します。それ以外の場合は、正の値を返します。より一般的には、入力を交換すると符号が逆になります:MONTHS_BETWEEN(d1, d2)
=-MONTHS_BETWEEN(d2, d1)
。1つの入力パラメーターに DATE 値を使用し、もう1つの入力パラメーターに TIMESTAMP を使用できます。
1つ以上の TIMESTAMP 値を使用しているものの、時刻に基づく小数の差異が必要ない場合は、 TIMESTAMP 式を DATE にキャストします。
整数値のみが必要な場合は、値を切り捨て、丸め、またはキャストできます。例:
SELECT ROUND(MONTHS_BETWEEN('2019-03-31 12:00:00'::TIMESTAMP, '2019-02-28 00:00:00'::TIMESTAMP)) AS MonthsBetween1; +----------------+ | MONTHSBETWEEN1 | |----------------| | 1 | +----------------+
入力がNULLの場合、結果はNULLになります。
例¶
この例は、月全体の違いを示しています。日付の最初のペアは、月の同じ日(15日)になります。日付の2番目のペアは、両方ともそれぞれの月の最後の日です(2月28日と3月31日)。
SELECT MONTHS_BETWEEN('2019-03-15'::DATE, '2019-02-15'::DATE) AS MonthsBetween1, MONTHS_BETWEEN('2019-03-31'::DATE, '2019-02-28'::DATE) AS MonthsBetween2; +----------------+----------------+ | MONTHSBETWEEN1 | MONTHSBETWEEN2 | |----------------+----------------| | 1.000000 | 1.000000 | +----------------+----------------+
次の例は、小数月の違いを示しています。
最初の列では、関数に2つの日付が渡されます。
2番目の列の場合、関数には、最初の列で使用されたものと同じ2つの日付を表す2つのタイムスタンプが渡されますが、時刻は異なります。時間の違いにより、2番目の列の差は1番目の列よりも大きくなっています。
3番目の列では、関数にそれぞれの月の同じ日を表す2つのタイムスタンプが渡されます。これにより、関数はタイムスタンプ間の時間差を無視するため、小数部分は0になります。
SELECT MONTHS_BETWEEN('2019-03-01'::DATE, '2019-02-15'::DATE) AS MonthsBetween1, MONTHS_BETWEEN('2019-03-01 02:00:00'::TIMESTAMP, '2019-02-15 01:00:00'::TIMESTAMP) AS MonthsBetween2, MONTHS_BETWEEN('2019-02-15 02:00:00'::TIMESTAMP, '2019-02-15 01:00:00'::TIMESTAMP) AS MonthsBetween3 ; +----------------+----------------+----------------+ | MONTHSBETWEEN1 | MONTHSBETWEEN2 | MONTHSBETWEEN3 | |----------------+----------------+----------------| | 0.548387 | 0.549731 | 0.000000 | +----------------+----------------+----------------+
月の日が同じ場合(例:2月28日と3月28日)と、月の日が最後の場合(例:2月28日と3月31日)の 両方 で、関数が月を整数で返すという事実は特に、ペア内で最初の日付を増やしても、必ずしも出力値が増えるわけではないという、非直観的な動作につながります。この例では、最初の日付が3月28日から3月30日に、次に3月31日まで増加するにつれて、差は1.0からより大きな数値に増加し、その後1.0まで減少します。
最初の列では、入力日は異なる月の同じ日を表すため、関数は結果の小数部分に対して
0
を返します。2番目の列の場合、入力日は異なる月の異なる日を表します(両方とも月の最後の日ではありません)。したがって、関数は結果の小数部分を計算します。
3番目の列の場合、入力日は2つの異なる月のそれぞれの最終日を表すため、関数は結果の小数部分に対して再び
0
を返します。SELECT MONTHS_BETWEEN('2019-03-28'::DATE, '2019-02-28'::DATE) AS MonthsBetween1, MONTHS_BETWEEN('2019-03-30'::DATE, '2019-02-28'::DATE) AS MonthsBetween2, MONTHS_BETWEEN('2019-03-31'::DATE, '2019-02-28'::DATE) AS MonthsBetween3 ; +----------------+----------------+----------------+ | MONTHSBETWEEN1 | MONTHSBETWEEN2 | MONTHSBETWEEN3 | |----------------+----------------+----------------| | 1.000000 | 1.064516 | 1.000000 | +----------------+----------------+----------------+
この例は、パラメーターの順序を逆にすると、結果の符号が逆になることを示しています。
SELECT MONTHS_BETWEEN('2019-03-01'::DATE, '2019-02-01'::DATE) AS MonthsBetween1, MONTHS_BETWEEN('2019-02-01'::DATE, '2019-03-01'::DATE) AS MonthsBetween2 ; +----------------+----------------+ | MONTHSBETWEEN1 | MONTHSBETWEEN2 | |----------------+----------------| | 1.000000 | -1.000000 | +----------------+----------------+