Ich möchte die Anzahl der Monate zwischen zwei Datums- und Uhrzeitfeldern berechnen.
Gibt es einen besseren Weg, als den Unix-Zeitstempel und die Division durch 2 592 000 (Sekunden) zu erhalten und innerhalb von MySQL aufzurunden?
mysql
date
datediff
date-arithmetic
Darryl Hein
quelle
quelle
PERIODDIFF
Nimmt einfach einen JJJJMM-Wert an. Wenn Sie also nicht die Tage selbst berücksichtigen, bevor Sie die JJJJMM-Werte übergeben, berechnen Sie nur die Anzahl der Monate, aufgerundet auf den nächsten Monat, wenn weniger als eine ganze Anzahl von Monaten vorhanden ist. Siehe Zanes Antwort unten.PERIODDIFF
Kommentar? Perioddiff nimmt keine Tageswerte an, daher berechnen Sie die Anzahl der Monate, die auf den nächsten Monat aufgerundet werden, wenn weniger als eine ganze Anzahl von Monaten vorhanden istMonatsdifferenz zwischen zwei Daten:
Ich bin überrascht, dass dies noch nicht erwähnt wurde:
Schauen Sie sich die Funktion TIMESTAMPDIFF () in MySQL an.
Auf diese Weise können Sie zwei
TIMESTAMP
oder mehrDATETIME
Werte (oder sogar,DATE
wenn MySQL automatisch konvertiert) sowie die Zeiteinheit übergeben, auf die Sie Ihre Differenz stützen möchten.Sie können
MONTH
im ersten Parameter als Einheit angeben :SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-04') -- Outputs: 0
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-05') -- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-06-15') -- Outputs: 1
SELECT TIMESTAMPDIFF(MONTH, '2012-05-05', '2012-12-16') -- Outputs: 7
Grundsätzlich wird die Anzahl der Monate angegeben, die seit dem ersten Datum in der Parameterliste vergangen sind. Diese Lösung kompensiert automatisch die unterschiedliche Anzahl von Tagen in jedem Monat (28, 30, 31) sowie die Berücksichtigung von Schaltjahren - Sie müssen sich um nichts davon kümmern.
Monatsunterschied mit Präzision:
Es ist etwas komplizierter, wenn Sie in der Anzahl der verstrichenen Monate eine Dezimalgenauigkeit einführen möchten, aber so können Sie dies tun:
SELECT TIMESTAMPDIFF(MONTH, startdate, enddate) + DATEDIFF( enddate, startdate + INTERVAL TIMESTAMPDIFF(MONTH, startdate, enddate) MONTH ) / DATEDIFF( startdate + INTERVAL TIMESTAMPDIFF(MONTH, startdate, enddate) + 1 MONTH, startdate + INTERVAL TIMESTAMPDIFF(MONTH, startdate, enddate) MONTH )
Wo
startdate
undenddate
sind Ihre Datumsparameter, sei es aus zwei Datumsspalten in einer Tabelle oder als Eingabeparameter aus einem Skript:Beispiele:
With startdate = '2012-05-05' AND enddate = '2012-05-27': -- Outputs: 0.7097
With startdate = '2012-05-05' AND enddate = '2012-06-13': -- Outputs: 1.2667
With startdate = '2012-02-27' AND enddate = '2012-06-02': -- Outputs: 3.1935
quelle
PERIODDIFF
Kommentar zur ausgewählten Antwort sind sehrPERIOD_DIFF berechnet Monate zwischen zwei Daten.
So berechnen Sie beispielsweise die Differenz zwischen now () und einer Zeitspalte in your_table:
select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;
quelle
Ich benutze auch PERIODDIFF . Um das Jahr und den Monat des Datums zu erhalten, benutze ich die Funktion EXTRACT :
SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;
quelle
DATE_FORMAT
Methode benötigt 50% weniger Zeit , danke! +1SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM FROM_UNIXTIME(time, "%Y%m%d"))) AS months FROM your_table;
PERIOD_DIFF
nimmt keine Tageswerte an, daher berechnen Sie die Anzahl der auf den nächsten Monat aufgerundeten Monate, wenn weniger als eine ganze Anzahl von Monaten vorhanden ist. Sie sollten Ihre Antwort bearbeiten, um dies zu verdeutlichen.Wie viele der Antworten hier zeigen, hängt die richtige Antwort genau davon ab, was Sie brauchen. In meinem Fall muss ich auf die nächste ganze Zahl runden .
Betrachten Sie diese Beispiele: 1. Januar -> 31. Januar: Es sind 0 ganze Monate und fast 1 Monat lang. 1. Januar -> 1. Februar? Es ist 1 ganzer Monat und genau 1 Monat lang.
Um die Anzahl der ganzen (vollständigen) Monate zu erhalten, verwenden Sie:
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31'); => 0 SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01'); => 1
Um eine gerundete Dauer in Monaten zu erhalten, können Sie Folgendes verwenden:
SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1 SELECT ROUND(TIMESTAMPDIFF(DAY, '2018-01-01', '2018-01-31')*12/365.24); => 1
Dies ist auf +/- 5 Tage und für Bereiche über 1000 Jahre genau. Zanes Antwort ist offensichtlich genauer, aber für meinen Geschmack zu ausführlich.
quelle
Aus dem MySQL-Handbuch:
So kann es möglich sein, so etwas zu tun:
Select period_diff(concat(year(d1),if(month(d1)<10,'0',''),month(d1)), concat(year(d2),if(month(d2)<10,'0',''),month(d2))) as months from your_table;
Wobei d1 und d2 die Datumsausdrücke sind.
Ich musste die if () - Anweisungen verwenden, um sicherzustellen, dass die Monate eine zweistellige Zahl wie 02 statt 2 waren.
quelle
Ich bevorzuge diesen Weg, weil jeder ihn auf den ersten Blick klar verstehen wird:
SELECT 12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months FROM tab;
quelle
Gibt es einen besseren Weg? Ja. Verwenden Sie keine MySQL-Zeitstempel. Abgesehen von der Tatsache, dass sie 36 Bytes belegen, ist es überhaupt nicht bequem, mit ihnen zu arbeiten. Ich würde empfehlen, Julian Date und Seconds ab Mitternacht für alle Datums- / Zeitwerte zu verwenden. Diese können zu einer UnixDateTime kombiniert werden. Wenn dies in einem DWORD (vorzeichenlose 4-Byte-Ganzzahl) gespeichert ist, können Daten bis zu 2106 als Sekunden seit dem Epoc gespeichert werden. 01.01.1970 DWORD max val = 4.294.967.295 - Ein DWORD kann 136 Jahre lang halten
Julian Dates sind sehr gut zu bearbeiten, wenn Datumsberechnungen durchgeführt werden. UNIXDateTime-Werte sind gut zu verwenden, wenn Datums- / Uhrzeitberechnungen durchgeführt werden mit, aber ich möchte einen Blick auf einen Blick.
Das Konvertieren zu Julian und zurück kann sehr schnell in einer guten Sprache erfolgen. Mit Zeigern habe ich es auf ungefähr 900 Clks reduziert (dies ist natürlich auch eine Konvertierung von einem STRING zu einem INTEGER).
Wenn Sie in ernsthafte Anwendungen geraten, die Datums- / Uhrzeitinformationen wie beispielsweise die Finanzmärkte verwenden, sind julianische Daten de facto.
quelle
Die Abfrage lautet wie folgt:
select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..
Gibt eine Anzahl von Kalendermonaten seit dem erstellten Datenstempel in einem Kundendatensatz an, sodass MySQL die Monatsauswahl intern vornehmen kann.
quelle
DROP FUNCTION IF EXISTS `calcula_edad` $$ CREATE DEFINER=`root`@`localhost` FUNCTION `calcula_edad`(pFecha1 date, pFecha2 date, pTipo char(1)) RETURNS int(11) Begin Declare vMeses int; Declare vEdad int; Set vMeses = period_diff( date_format( pFecha1, '%Y%m' ), date_format( pFecha2, '%Y%m' ) ) ; /* Si el dia de la fecha1 es menor al dia de fecha2, restar 1 mes */ if day(pFecha1) < day(pFecha2) then Set vMeses = VMeses - 1; end if; if pTipo='A' then Set vEdad = vMeses div 12 ; else Set vEdad = vMeses ; end if ; Return vEdad; End select calcula_edad(curdate(),born_date,'M') -- for number of months between 2 dates
quelle
Wenn Sie diesen Code ausführen, wird eine Funktion mit Datumsdifferenz erstellt, die den Unterschied im Datumsformat JJJJ-MM-TT anzeigt.
DELIMITER $$ CREATE FUNCTION datedifference(date1 DATE, date2 DATE) RETURNS DATE NO SQL BEGIN DECLARE dif DATE; IF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < 0 THEN SET dif=DATE_FORMAT( CONCAT( PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , '-', PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , '-', DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(DATE_SUB(date1, INTERVAL 1 MONTH)), '-', DAY(date2))))), '%Y-%m-%d'); ELSEIF DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2)))) < DAY(LAST_DAY(DATE_SUB(date1, INTERVAL 1 MONTH))) THEN SET dif=DATE_FORMAT( CONCAT( PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , '-', PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , '-', DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))), '%Y-%m-%d'); ELSE SET dif=DATE_FORMAT( CONCAT( PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))DIV 12 , '-', PERIOD_DIFF(date_format(date1, '%y%m'),date_format(date2, '%y%m'))% 12 , '-', DATEDIFF(date1, DATE(CONCAT(YEAR(date1),'-', MONTH(date1), '-', DAY(date2))))), '%Y-%m-%d'); END IF; RETURN dif; END $$ DELIMITER;
quelle
Dies hängt davon ab, wie die Anzahl der Monate definiert werden soll. Beantworten Sie diese Fragen: "Was ist der Unterschied in Monaten: 15. Februar 2008 - 12. März 2009". Wird es durch eine eindeutige Anzahl von Tagen definiert, die von den Schaltjahren abhängt - welcher Monat es ist oder der gleiche Tag des Vormonats = 1 Monat.
Eine Berechnung für Tage :
15. Februar -> 29 (Schaltjahr) = 14. März 2008 + 365 = 1. März 2009. 1. März -> 12. März = 12 Tage. 14 + 365 + 12 = 391 Tage. Gesamt = 391 Tage / (durchschnittliche Tage im Monat = 30) = 13.03333
Eine Berechnung der Monate :
15. Februar 2008 - 15. Februar 2009 = 12. Februar 15 -> 12. März = weniger als 1 Monat Gesamt = 12 Monate oder 13, wenn der 15. Februar - 12. März als "letzter Monat" betrachtet wird
quelle
SELECT * FROM emp_salaryrevise_view WHERE curr_year Between '2008' AND '2009' AND MNTH Between '12' AND '1'
quelle
Ich brauchte einen Monatsunterschied mit Präzision. Obwohl die Lösung von Zane Bien in die richtige Richtung geht, liefern sein zweites und drittes Beispiel ungenaue Ergebnisse. Ein Tag im Februar geteilt durch die Anzahl der Tage im Februar entspricht nicht einem Tag im Mai geteilt durch die Anzahl der Tage im Mai. Das zweite Beispiel sollte also ((31-5 + 1) / 31 + 13/30 =) 1.3043 und das dritte Beispiel ((29-27 + 1) / 29 + 2/30 + 3 =) 3.1701 ausgeben.
Am Ende hatte ich folgende Abfrage:
SELECT '2012-02-27' AS startdate, '2012-06-02' AS enddate, TIMESTAMPDIFF(DAY, (SELECT startdate), (SELECT enddate)) AS days, IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), 0, (TIMESTAMPDIFF(DAY, (SELECT startdate), LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY)) / DAY(LAST_DAY((SELECT startdate)))) AS period1, TIMESTAMPDIFF(MONTH, LAST_DAY((SELECT startdate)) + INTERVAL 1 DAY, LAST_DAY((SELECT enddate))) AS period2, IF(MONTH((SELECT startdate)) = MONTH((SELECT enddate)), (SELECT days), DAY((SELECT enddate))) / DAY(LAST_DAY((SELECT enddate))) AS period3, (SELECT period1) + (SELECT period2) + (SELECT period3) AS months
quelle
PERIOD_DIFF () Funktion
Eine der Möglichkeiten ist, dass MySQL PERIOD_DIFF () die Differenz zwischen zwei Perioden zurückgibt. Perioden sollten das gleiche Format haben, dh JJJJMM oder JJMM. Es ist zu beachten, dass Perioden keine Datumswerte sind.
Code:
SELECT PERIOD_DIFF(200905,200811);
quelle
Sie können Jahre, Monate und Tage auf diese Weise erhalten:
SELECT username ,date_of_birth ,DATE_FORMAT(CURDATE(), '%Y') - DATE_FORMAT(date_of_birth, '%Y') - (DATE_FORMAT(CURDATE(), '00-%m-%d') < DATE_FORMAT(date_of_birth, '00-%m-%d')) AS years ,PERIOD_DIFF( DATE_FORMAT(CURDATE(), '%Y%m') , DATE_FORMAT(date_of_birth, '%Y%m') ) AS months ,DATEDIFF(CURDATE(),date_of_birth) AS days FROM users
quelle
Sie können dies auch versuchen:
select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name;
ODER
select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name;
quelle
Einfache Antwort mit Startdatum als ins_frm und Enddatum als ins_to
SELECT convert(TIMESTAMPDIFF(year, ins_frm, ins_to),UNSIGNED) as yrs, mod(TIMESTAMPDIFF(MONTH, ins_frm, ins_to),12) mnths FROM table_name
Genießen :)))
quelle
Versuche dies
SELECT YEAR(end_date)*12 + MONTH(end_date) - (YEAR(start_date)*12 + MONTH(start_date))
quelle
Diese Abfrage hat bei mir funktioniert :)
SELECT * FROM tbl_purchase_receipt WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'
Es dauert einfach zwei Daten und ruft die Werte zwischen ihnen ab.
quelle