我想计算两个日期之间的月数。
做:
SELECT TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40';
返回: 0年0个月409天20小时0分0.00秒
所以:
SELECT extract(month from TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40');
返回0.
答案 0 :(得分:26)
age
函数返回interval:
age(timestamp1, timestamp2)
然后我们尝试从间隔中提取年份和月份并相应地添加它们:
select extract(year from age(timestamp1, timestamp2)) * 12 +
extract(month from age(timestamp1, timestamp2))
答案 1 :(得分:13)
age
函数给出了合理的间隔:
SELECT age(TIMESTAMP '2012-06-13 10:38:40', TIMESTAMP '2011-04-30 14:38:40');
返回1 year 1 mon 12 days 20:00:00
,您可以轻松使用EXTRACT
来计算月数:
SELECT EXTRACT(YEAR FROM age) * 12 + EXTRACT(MONTH FROM age) AS months_between
FROM age(TIMESTAMP '2012-06-13 10:38:40', TIMESTAMP '2011-04-30 14:38:40') AS t(age);
答案 2 :(得分:8)
如果您多次执行此操作,则可以定义以下function:
CREATE FUNCTION months_between (t_start timestamp, t_end timestamp)
RETURNS integer
AS $$
SELECT
(
12 * extract('years' from a.i) + extract('months' from a.i)
)::integer
from (
values (justify_interval($2 - $1))
) as a (i)
$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
这样你就可以
了SELECT months_between('2015-01-01', now());
答案 3 :(得分:3)
请注意,当您尝试使用日历月差异时,@ram和@angelin的投票最多是不准确的。
select extract(year from age(timestamp1, timestamp2))*12 + extract(month from age(timestamp1, timestamp2))
例如,如果您尝试这样做:
select extract(year from age('2018-02-02'::date, '2018-03-01'::date))*12 + extract(month from age('2018-02-02'::date , '2018-03-01'::date))
结果将为0 ,但无论日期之间的天数如何,从2月开始的3月之间的月份应为1。
因此公式应类似于以下说法,我们以timestamp1和timestamp2开头:
(((year2-year1)* 12)-month1 + month2 =两个时间戳之间的日历月
pg中的会被翻译为:
select ((extract('years' from '2018-03-01 00:00:00'::timestamp)::int - extract('years' from '2018-02-02 00:00:00'::timestamp)::int) * 12)
- extract('month' from '2018-02-02 00:00:00'::timestamp)::int + extract('month' from '2018-03-01 00:00:00'::timestamp)::int;
您可以创建类似的功能
CREATE FUNCTION months_between (t_start timestamp, t_end timestamp)
RETURNS integer
AS $$
select ((extract('years' from $2)::int - extract('years' from $1)::int) * 12)
- extract('month' from $1)::int + extract('month' from $2)::int
$$
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
答案 4 :(得分:2)
给出两个月的两个月的差异
SELECT ((extract( year FROM TIMESTAMP '2012-06-13 10:38:40' ) - extract( year FROM TIMESTAMP '2011-04-30 14:38:40' )) *12) + extract(MONTH FROM TIMESTAMP '2012-06-13 10:38:40' ) - extract(MONTH FROM TIMESTAMP '2011-04-30 14:38:40' );
结果:14
必须分别提取几个月的日期,然后两个结果的差异
答案 5 :(得分:2)
SELECT date_part ('year', f) * 12
+ date_part ('month', f)
FROM age ('2015-06-12', '2014-12-01') f
结果:6个月
答案 6 :(得分:1)
我曾经遇到过同样的问题并且写了这个......这很难看:
postgres=> SELECT floor((extract(EPOCH FROM TIMESTAMP '2012-06-13 10:38:40' ) - extract(EPOCH FROM TIMESTAMP '2005-04-30 14:38:40' ))/30.43/24/3600);
floor
-------
85
(1 row)
在这个解决方案中,“一个月”被定义为30.43天,所以它可能会在较短的时间内产生一些意想不到的结果。
答案 7 :(得分:0)
试试这个解决方案:
SELECT extract (MONTH FROM age('2014-03-03 00:00:00'::timestamp,
'2013-02-03 00:00:00'::timestamp)) + 12 * extract (YEAR FROM age('2014-03-03
00:00:00'::timestamp, '2013-02-03 00:00:00'::timestamp)) as age_in_month;
答案 8 :(得分:0)
SELECT floor(extract(days from TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP
'2011-04-30 14:38:40')/30.43)::integer as months;
给出近似值但避免重复时间戳。这使用来自tobixen's answer的提示除以30来代替30而对于计算月数的长时间间隔不太正确。
答案 9 :(得分:0)
按年份和月份提取将取决于月份:
select extract(year from age('2016-11-30'::timestamp, '2015-10-15'::timestamp)); --> 1
select extract(month from age('2016-11-30'::timestamp, '2015-10-15'::timestamp)); --> 1
--> Total 13 months
这种方法可以维持几个月的时间(感谢使用除虫剂Tobixen)
select round(('2016-11-30'::date - '2015-10-15'::date)::numeric /30.43, 1); --> 13.5 months
答案 10 :(得分:0)
我做了一个这样的函数:
/* similar to ORACLE's MONTHS_BETWEEN */
CREATE OR REPLACE FUNCTION ORACLE_MONTHS_BETWEEN(date_from DATE, date_to DATE)
RETURNS REAL LANGUAGE plpgsql
AS
$$
DECLARE age INTERVAL;
declare rtn real;
BEGIN
age := age(date_from, date_to);
rtn := date_part('year', age) * 12 + date_part('month', age) + date_part('day', age)/31::real;
return rtn;
END;
$$;
Oracle 示例)
SELECT MONTHS_BETWEEN
(TO_DATE('2015-02-02','YYYY-MM-DD'), TO_DATE('2014-12-01','YYYY-MM-DD') )
"Months" FROM DUAL;
--result is: 2.03225806451612903225806451612903225806
我的 PostgreSQL 函数示例)
select ORACLE_MONTHS_BETWEEN('2015-02-02'::date, '2014-12-01'::date) Months;
-- result is: 2.032258
根据结果,您可以使用 CEIL()/FLOOR() 进行四舍五入。
select ceil(2.032258) --3
select floor(2.032258) --2
答案 11 :(得分:-2)
尝试;
select extract(month from age('2012-06-13 10:38:40'::timestamp, '2011-04-30 14:38:40'::timestamp)) as my_months;