简化两个日期之间月份的计算(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;
这个问题被问了很多次,建议的查询之一是在 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;