Месяцы между двумя датами

В oracle я могу узнать нет: месяцев между использованием функции MONTHS_BETWEEN.

В postgres я использую для этого функцию extract. eg.like

select 
    extract(year from age(current_date, '2012-12-09')) * 12
    + 
    extract(month from age(current_date, '2012-12-09'))

Есть ли другие способы (встроенные функции) в postgres?

Ответ 1

Это легко повторить в PostgreSQL, просто используя функции SQL, чтобы убрать то, что у вас уже есть:

create function months_of(interval)
 returns int strict immutable language sql as $$
  select extract(years from $1)::int * 12 + extract(month from $1)::int
$$;

create function months_between(date, date)
 returns int strict immutable language sql as $$
   select abs(months_of(age($1, $2)))
$$;

И теперь select months_between('1978-06-20', '2011-12-09') производит 401.

Ответ 2

К сожалению, это не так, потому что extract(month ...) возвращает число месяцев по модулю 12.

Есть одно небольшое упрощение, которое вы можете сделать; удалить первый параметр age() - значение по умолчанию - возраст от current_date, поэтому эти два эквивалента:

age(current_date, '2012-12-09')
age('2012-12-09')

Ответ 3

Вы можете использовать UDF, например. Я нашел здесь здесь:

   CREATE OR REPLACE FUNCTION DateDiff (units VARCHAR(30), start_t TIMESTAMP, end_t TIMESTAMP) 
     RETURNS INT AS $$
   DECLARE
     diff_interval INTERVAL; 
     diff INT = 0;
     years_diff INT = 0;
   BEGIN
     IF units IN ('yy', 'yyyy', 'year', 'mm', 'm', 'month') THEN
       years_diff = DATE_PART('year', end_t) - DATE_PART('year', start_t);

       IF units IN ('yy', 'yyyy', 'year') THEN
         -- SQL Server does not count full years passed (only difference between year parts)
         RETURN years_diff;
       ELSE
         -- If end month is less than start month it will subtracted
         RETURN years_diff * 12 + (DATE_PART('month', end_t) - DATE_PART('month', start_t)); 
       END IF;
     END IF;

     -- Minus operator returns interval 'DDD days HH:MI:SS'  
     diff_interval = end_t - start_t;

     diff = diff + DATE_PART('day', diff_interval);

     IF units IN ('wk', 'ww', 'week') THEN
       diff = diff/7;
       RETURN diff;
     END IF;

     IF units IN ('dd', 'd', 'day') THEN
       RETURN diff;
     END IF;

     diff = diff * 24 + DATE_PART('hour', diff_interval); 

     IF units IN ('hh', 'hour') THEN
        RETURN diff;
     END IF;

     diff = diff * 60 + DATE_PART('minute', diff_interval);

     IF units IN ('mi', 'n', 'minute') THEN
        RETURN diff;
     END IF;

     diff = diff * 60 + DATE_PART('second', diff_interval);

     RETURN diff;
   END;
   $$ LANGUAGE plpgsql;

Ответ 4

SELECT date_part ('year', f) * 12
      + date_part ('month', f)
FROM age (CURRENT_DATE, '2014-12-01') f