2012-06-13 128 views
15

我想計算兩個日期之間的月數。在postgresql上的兩個時間戳之間計算幾個月?

做:

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

回答

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

不得不seperately提取個月的日期,然後對兩個結果

+0

我認爲我們在路上,但它仍然是越野車。結果與您的主張是14和良好的迴應是13. – GaetanZ

+1

select EXTRACT(year FROM age(TIMESTAMP'2012-06-13 10:38:40',TIMESTAMP'2011-04-30 14:38:40') )* 12 + EXTRACT(month from age(TIMESTAMP'2012-06-13 10:38:40',TIMESTAMP'2011-04-30 14:38:40')); – GaetanZ

+0

你是否得到了具有年齡功能的結果.... @GaetanZ:欣賞我的努力 –

2

的我很久了同樣的問題曾經寫了這樣的差別?這是相當難看:

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天長,所以它可以在更短的時間跨度給出一些意想不到的結果。

+0

它的工作,但它很奇怪。我看到的另一個問題是,你認爲一個月是30天。從2月3日到3月4日,有一個月。你的選擇將返回0.從1月3日到2月2日,沒有一個月。您的選擇將返回一個。 – GaetanZ

+0

是的,不幸的是它只是大致正確(但對我來說足夠好)。 (編輯它使其更清楚)。 – tobixen

+0

由於使用'30'而近似,因爲月份可以更長或更短 - 時間戳之間的距離越大,這成爲問題 - 相似的時間戳舍入就足夠了。 – pstanton

-1

嘗試;

select extract(month from age('2012-06-13 10:38:40'::timestamp, '2011-04-30 14:38:40'::timestamp)) as my_months; 
+1

這個答案是錯誤的。它返回'1',因爲'extract'只考慮月份,但不包括你有多少個月,因爲差異涉及多年。 –

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; 
6

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); 
+0

巧添加年和月:) – Andrew

13
age(timestamp1, timestamp2) => returns interval 

我們嘗試提取年份和月份,並相應地添加它們。

選擇提取物(一年年齡(timestamp1,timestamp2))* 12 + 提取物(從年齡(timestamp1月,timestamp2))

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

結果:6個月

4

如果您多次執行此操作,可以定義以下內容: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()); 
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.43來代替30,對於計算月份的長時間段不太不正確。

相關問題