2012-06-13 7 views
15

Ich möchte die Anzahl der Monate zwischen zwei Daten zählen.Anzahl der Monate zwischen zwei Zeitstempel auf PostgreSQL?

Doing:

SELECT TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40'; 

Returns: 0 Jahre 0 mons 409 Tage 20 Stunden 0 Minuten 0,00 Sekunden

und so:

SELECT extract(month from TIMESTAMP '2012-06-13 10:38:40' - TIMESTAMP '2011-04-30 14:38:40'); 

kehrt 0.

Antwort

2

Gewährt der Unterschied der Monate von zwei Daten

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'); 

Das Ergebnis: 14

Monate separat extrahieren sowohl für die Tage und dann die Differenz der beiden Ergebnisse

+0

Ich denke, wir sind auf dem Weg, aber es ist immer noch fehlerhaft. Das Ergebnis mit Ihrem Vorschlag ist 14 und die gute Antwort ist 13. – GaetanZ

+1

wählen EXTRACT (Jahr von Alter (Timestamp '2012-06-13 10: 38: 40', Timestamp '2011-04-30 14:38:40')) * 12 + EXTRAKT (Monat FROM Alter (TIMESTAMP '2012-06-13 10: 38: 40', TIMESTAMP '2011-04-30 14:38:40')); – GaetanZ

+0

Haben Sie das Ergebnis mit Altersfunktion .... @GaetanZ: zu meiner Mühe zu schätzen –

2

Ich hatte das gleiche Problem war einmal und schrieb dieses ... es ist ziemlich hässlich:

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) 

In dieser Lösung „1 Monat“ definiert ist 30,43 Tage lang sein, so kann es einige unerwartete Ergebnisse über kürzere Zeitspannen geben.

+0

Es funktioniert, aber es ist sehr seltsam. Das andere Problem, das ich sehe, ist die Tatsache, dass Sie denken, dass ein Monat 30 Tage ist. Vom 3. Februar bis 4. März gibt es einen Monat. Ihre Auswahl gibt 0 zurück. Und vom 3. Januar bis 2. Februar gibt es keinen Monat. Ihre Auswahl gibt eins zurück. – GaetanZ

+0

Ja, leider ist es nur ungefähr richtig (aber es war gut genug für mich). (bearbeitet, um es klarer zu machen). – tobixen

+0

seine ungefähren wegen der Verwendung von "30", da Monate länger oder kürzer sein können - je größer der Abstand zwischen den Zeitstempeln, desto mehr wird dies ein Problem - ähnliche Timestamps Rundung wird ausreichen. – pstanton

-1

Versuchen Sie;

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

Diese Antwort ist falsch. Es gibt '1' zurück, weil 'extract' nur den Monat berücksichtigt, aber nicht wie viele Monate Sie haben, aufgrund der Jahre, die in den Unterschied involviert sind. –

0

Versuchen Sie, diese Lösung:

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

Die age Funktion ein berechtigtes Intervall geben, mit zu arbeiten:

SELECT age(TIMESTAMP '2012-06-13 10:38:40', TIMESTAMP '2011-04-30 14:38:40'); 

kehrt 1 year 1 mon 12 days 20:00:00 und mit, dass man leicht EXTRACT verwenden können, die zählen Anzahl der Monate:

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

Clever, um Jahre und Monate hinzuzufügen :) – Andrew

13
age(timestamp1, timestamp2) => returns interval 

Wir versuchen Jahr und Monat aus dem Intervall zu extrahieren und fügen sie entsprechend hinzu.

select-Extrakt (Jahr ab dem Alter (timestamp1, timestamp2)) * 12 + Extrakt (Monat ab dem Alter (timestamp1, timestamp2))

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

Ergebnis: 6 Monate

4

Wenn Sie dies mehrere Male tun, können Sie Folgendes definieren: function:

, so dass Sie dann nur

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; 

geben einen ungefähren Wert aber Vervielfältigung von Zeitstempel vermeiden.Dies verwendet einen Hinweis von tobixen's answer, um durch 30,43 anstelle von 30 zu dividieren, um für lange Zeitspannen während der Berechnung von Monaten weniger falsch zu sein.

Verwandte Themen