简化两个日期之间月份的计算(postgresql)

Simplify calculation of months between 2 dates (postgresql)

这个问题被问了很多次,建议的查询之一是在 2 个日期之间获取月份不工作。

SELECT date_part('month',age('2016-06-30', '2018-06-30'))

本次查询结果为0,应该是24个月。因为两个日期的月份都是 06。

这有效,但与 sql 服务器功能相比有点笨拙:

SELECT date_part ('year', f) * 12 + date_part ('month', f) 
FROM age ('2016-06-30', '2018-06-30') f

喜欢sql服务器(我认为):

DATEDIFF(month, date1, date2)

在 Postgresql 中没有简单的方法(如上面)来计算 2 个日期之间的月份吗?如果可能的话,我宁愿不使用函数。

很遗憾,您已经有了最优雅的解决方案。

如果您查看 extract 的文档(与 date_part 相同):

https://www.postgresql.org/docs/current/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT

month

For timestamp values, the number of the month within the year (1 - 12) ; for interval values, the number of months, modulo 12 (0 - 11)

SELECT EXTRACT(MONTH FROM TIMESTAMP '2001-02-16 20:38:40');
Result: 2

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 3 months');
Result: 3

SELECT EXTRACT(MONTH FROM INTERVAL '2 years 13 months');
Result: 1

对于你的问题,如果 month 有一个不是模 12 但不存在的版本就好了。

您的选项(提取年份 * 12 + 月份)是现有的最佳选项。


编辑

如果您确实想创建一个函数,请查看以下两个函数:

CREATE OR REPLACE FUNCTION get_months(i interval) RETURNS double precision AS $$
    SELECT date_part ('year', i) * 12 + date_part ('month', i) ;
$$ LANGUAGE SQL IMMUTABLE;


SELECT get_months(age('2016-06-30', '2018-06-30'));

CREATE OR REPLACE FUNCTION get_months(to_date date, from_date date) RETURNS double precision AS $$
    SELECT date_part ('year', f) * 12 + date_part ('month', f) 
      FROM age (to_date, from_date) f;
$$ LANGUAGE SQL IMMUTABLE;


SELECT get_months('2016-06-30', '2018-06-30');

您实际上可以创建两者,然后只使用适合您的代码的那个。

这将为您提供两个日期之间的月数,不包括天数。

CREATE OR REPLACE FUNCTION get_months_between(to_date date, from_date date) RETURNS double precision AS $$
    SELECT (date_part ('year', to_date) * 12 + date_part ('month', to_date)) - (date_part ('year', from_date) * 12 + date_part ('month', from_date))

$$ LANGUAGE SQL IMMUTABLE;