- Categorias:
MONTHS_BETWEEN¶
Retorna o número de meses entre dois valores DATE ou TIMESTAMP.
Por exemplo, MONTHS_BETWEEN('2020-02-01'::DATE, '2020-01-01'::DATE)
retorna 1.0.
- Consulte também:
Sintaxe¶
MONTHS_BETWEEN( <date_expr1> , <date_expr2> )
Argumentos¶
date_expr1
A data da qual é feita a subtração.
date_expr2
A data a ser subtraída.
Retornos¶
FLOAT representando o número de meses entre as duas datas.
O número é calculado conforme descrito abaixo:
A porção inteira do FLOAT é calculada usando as partes do ano e do mês dos valores de entrada.
Na maioria das situações, a parte fracionada é calculada usando as partes do dia e da hora dos valores de entrada. (Ao calcular a fração de um mês, a função considera cada mês como 31 dias de duração).
No entanto, há duas exceções:
Se os dias do mês forem os mesmos (por exemplo, 28 de fevereiro e 28 de março), a parte fracionada será zero, mesmo que um ou ambos os valores de entrada sejam carimbos de data/hora e as horas sejam diferentes.
Se os dias do mês forem ambos o último dia do mês (por exemplo, fevereiro 28 e março 31), a parte fracionada será zero, mesmo que os dias do mês não sejam os mesmos.
Por exemplo, a função considera cada um dos seguintes pares de carimbo de data/hora/datas com um intervalo exato de 1,0 mês:
Carimbo de data/hora 1
Carimbo de data/hora 2
Notas
2019-03-01 02:00:00
2019-02-01 13:00:00
O mesmo dia de cada mês.
2019-03-28
2019-02-28
O mesmo dia de cada mês.
2019-03-31
2019-02-28
Último dia de cada mês.
2019-03-31 01:00:00
2019-02-28 13:00:00
Último dia de cada mês.
Notas de uso¶
Se a data (ou carimbo de data/hora) d1 representar um ponto no tempo anterior a d2, então
MONTHS_BETWEEN(d1, d2)
retornará um valor negativo; caso contrário, retornará um valor positivo. De modo mais geral, a troca das entradas reverte o sinal:MONTHS_BETWEEN(d1, d2)
=-MONTHS_BETWEEN(d2, d1)
.Você pode usar um valor DATE para um parâmetro de entrada e um TIMESTAMP para o outro.
Se você usar um ou mais valores TIMESTAMP, mas não quiser diferenças fracionais baseadas na hora do dia, então converta suas expressões TIMESTAMP em DATE.
Se você quiser apenas valores inteiros, você poderá truncar, arredondar ou converter o valor. Por exemplo:
SELECT ROUND(MONTHS_BETWEEN('2019-03-31 12:00:00'::TIMESTAMP, '2019-02-28 00:00:00'::TIMESTAMP)) AS MonthsBetween1; +----------------+ | MONTHSBETWEEN1 | |----------------| | 1 | +----------------+
Se alguma entrada for NULL, o resultado será NULL.
Exemplos¶
Este exemplo mostra diferenças em meses inteiros. O primeiro par de datas tem o mesmo dia do mês (15). O segundo par de datas são os dois últimos dias em seus respectivos meses (28 de fevereiro e 31 de março).
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 | +----------------+----------------+
O próximo exemplo mostra diferenças nos meses fracionários.
Para a primeira coluna, a função é aprovada em duas datas.
Para a segunda coluna, dois carimbos de data/hora são passados na função que representam as mesmas duas datas que foram usadas para a primeira coluna, mas com horas diferentes. A diferença na segunda coluna é maior do que na primeira devido às diferenças na hora.
Para a terceira coluna, dois carimbos de data/hora são passados na função que representam o mesmo dia de seus respectivos meses. Isto faz com que a função ignore quaisquer diferenças de hora entre os carimbos de data/hora, de modo que a parte fracionária seja 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 | +----------------+----------------+----------------+
O fato de a função retornar um número inteiro de meses tanto quando os dias do mês são os mesmos (por exemplo, 28 de fevereiro e 28 de março) e quando os dias do mês são o último dia do mês (por exemplo, 28 de fevereiro e 31 de março) pode levar a um comportamento não intuitivo; especificamente, o aumento da primeira data no par nem sempre aumenta o valor de saída. Neste exemplo, como a primeira data aumenta de 28 de março para 30 de março, e depois para 31 de março, a diferença aumenta de 1,0 para um número maior e depois diminui de volta para 1,0.
Para a primeira coluna, as datas de entrada representam o mesmo dia em meses diferentes, portanto a função retorna
0
para a parte fracionária do resultado.Para a segunda coluna, as datas de entrada representam dias diferentes em meses diferentes (e não são ambos o último dia do mês), então a função calcula a parte fracionária do resultado.
Para a terceira coluna, as datas de entrada representam os últimos dias em cada um de dois meses diferentes, portanto a função retorna novamente
0
para a parte fracionária do resultado.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 | +----------------+----------------+----------------+
Este exemplo mostra que a inversão da ordem dos parâmetros inverte o sinal do resultado:
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 | +----------------+----------------+