Domanda

Sto cercando di calcolare il numero di mesi tra 2 campi di data e ora.

C'è un modo migliore che ottenere il timestamp unix e la divisione per 2 592 000 (secondi) e arrotondare con MySQL?

È stato utile?

Soluzione

Il DATEDIFF La funzione può darti il ??numero di giorni tra due date. Quale è più preciso, dal momento che ... come definisci un mese? (28, 29, 30 o 31 giorni?)

Altri suggerimenti

Differenza mensile tra due date date:

Sono sorpreso che questo non sia stato ancora menzionato:

Dai un'occhiata al < strong> TIMESTAMPDIFF () in MySQL.

Ciò che ti consente di fare è passare due valori TIMESTAMP o DATETIME (o anche DATE mentre MySQL si convertirà automaticamente) come nonché l'unità di tempo su cui vuoi basare la tua differenza.

Puoi specificare MONTH come unità nel primo parametro:

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

Praticamente ottiene il numero di mesi trascorsi dalla prima data nell'elenco dei parametri. Questa soluzione compensa automaticamente la quantità variabile di giorni in ogni mese (28,30,31) e tiene conto degli anni bisestili: non devi preoccuparti di nessuna di queste cose.


Differenza mese con precisione:

È un po 'più complicato se si desidera introdurre la precisione decimale nel numero di mesi trascorsi, ma ecco come è possibile farlo:

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
  )

Dove startdate e enddate sono i parametri della tua data, che si tratti di due colonne di date in una tabella o come parametri di input da uno script:

Esempi:

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

PERIOD_DIFF calcola i mesi tra due date.

Ad esempio, per calcolare la differenza tra now () e una colonna temporale in your_table:

select period_diff(date_format(now(), '%Y%m'), date_format(time, '%Y%m')) as months from your_table;

Uso anche PERIODDIFF . Per ottenere l'anno e il mese della data, utilizzo la funzione ESTRATTO :

  SELECT PERIOD_DIFF(EXTRACT(YEAR_MONTH FROM NOW()), EXTRACT(YEAR_MONTH FROM time)) AS months FROM your_table;

Preferisco così, perché tutti lo capiranno chiaramente al primo sguardo:

SELECT
    12 * (YEAR(to) - YEAR(from)) + (MONTH(to) - MONTH(from)) AS months
FROM
    tab;

Come mostrano molte delle risposte qui, la risposta "giusta" dipende esattamente da ciò di cui hai bisogno. Nel mio caso, devo arrotondare al numero intero più vicino .

Considera questi esempi: 1 gennaio - > 31 gennaio: sono 0 mesi interi e quasi 1 mese. 1 gennaio - > 1 febbraio? È 1 mese intero e esattamente 1 mese.

Per ottenere il numero di interi (completi) , utilizzare:

SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-01-31');  => 0
SELECT TIMESTAMPDIFF(MONTH, '2018-01-01', '2018-02-01');  => 1

Per ottenere una arrotondata in mesi, puoi utilizzare:

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

Questo è preciso a +/- 5 giorni e per intervalli superiori a 1000 anni. La risposta di Zane è ovviamente più accurata, ma è troppo dettagliata per i miei gusti.

Dal manuale di MySQL:

  

PERIOD_DIFF (P1, P2)

     

Restituisce il numero di mesi tra i periodi P1 e P2. P1 e P2 devono essere nel formato AAAA o AAAAMM. Si noti che gli argomenti del periodo P1 e P2 non sono valori di data.

     

mysql > SELEZIONA PERIOD_DIFF (200802.200703);           - > 11

Quindi potrebbe essere possibile fare qualcosa del genere:

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;

Dove d1 e d2 sono le espressioni di data.

Ho dovuto usare le istruzioni if ??() per assicurarmi che i mesi fossero un numero a due cifre come 02 anziché 2.

C'è un modo migliore? sì. Non utilizzare i timestamp MySQL. A parte il fatto che occupano 36 byte, non sono affatto convenienti con cui lavorare. Consiglierei di utilizzare Julian Date e Seconds da mezzanotte per tutti i valori di data / ora. Questi possono essere combinati per formare un UnixDateTime. Se questo è memorizzato in un DWORD (numero intero di 4 byte senza segno), le date fino al 2106 possono essere memorizzate come secondi da epoc, 01/01/1970 DWORD max val = 4.294.967.295 - Un DWORD può contenere 136 anni di secondi

Le date di Julian sono molto belle con cui lavorare quando si effettuano i calcoli della data I valori di UNIXDateTime sono utili per lavorare quando si eseguono calcoli di data / ora Né sono belli da guardare, quindi uso i timestamp quando ho bisogno di una colonna con cui non farò molti calcoli, ma voglio un'indicazione a colpo d'occhio.

La conversione in giuliano e viceversa può essere eseguita molto rapidamente in una buona lingua. Usando i puntatori l'ho ridotto a circa 900 Clks (questa è anche una conversione da STRING a un INTEGER ovviamente)

Quando entri in applicazioni serie che utilizzano informazioni su data / ora come ad esempio i mercati finanziari, le date giuliane sono di fatto.

La query sarà simile a:

select period_diff(date_format(now(),"%Y%m"),date_format(created,"%Y%m")) from customers where..

Fornisce un numero di mesi di calendario da quando è stato creato il datestamp su un record cliente, consentendo a MySQL di effettuare la selezione del mese internamente.

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

Esegui questo codice e creerà una funzione datedifferenza che ti darà la differenza nel formato della data aaaa-mm-gg.

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;

Dipende da come si desidera definire il numero di mesi. Rispondi a queste domande: "Qual è la differenza in mesi: 15 febbraio 2008 - 12 marzo 2009". È definito da un chiaro numero di giorni che dipende dagli anni bisestili, di che mese è o dello stesso giorno del mese precedente = 1 mese.

Un calcolo per giorni :

15 febbraio - > 29 (anno bisestile) = 14 1-mar-2008 + 365 = 1-mar-2009. 1 marzo - > Mar 12 = 12 giorni. 14 + 365 + 12 = 391 giorni. Totale = 391 giorni / (giorni medi nel mese = 30) = 13.03333

Un calcolo dei mesi :

15 febbraio 2008 - 15 febbraio 2009 = 12 15 febbraio - > Mar 12 = meno di 1 mese Totale = 12 mesi o 13 se il 15 febbraio - 12 marzo è considerato "il mese scorso"

SELECT * 
FROM emp_salaryrevise_view 
WHERE curr_year Between '2008' AND '2009' 
    AND MNTH Between '12' AND '1'

Avevo bisogno della differenza del mese con precisione. Sebbene la soluzione di Zane Bien sia nella giusta direzione, il suo secondo e terzo esempio danno risultati imprecisi. Un giorno di febbraio diviso per il numero di giorni di febbraio non è uguale a un giorno di maggio diviso per il numero di giorni di maggio. Quindi il secondo esempio dovrebbe produrre ((31-5 + 1) / 31 + 13/30 =) 1.3043 e il terzo esempio ((29-27 + 1) / 29 + 2/30 + 3 =) 3.1701.

Ho finito con la seguente query:

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

Puoi ottenere anni, mesi e giorni in questo modo:

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

Puoi anche provare questo:

select MONTH(NOW())-MONTH(table_date) as 'Total Month Difference' from table_name;

o

select MONTH(Newer_date)-MONTH(Older_date) as 'Total Month Difference' from table_Name;

PERIOD_DIFF () funzione

Uno dei modi è MySQL PERIOD_DIFF () restituisce la differenza tra due periodi. I periodi devono essere nello stesso formato, ad esempio AAAAMM o AAA. Va notato che i periodi non sono valori di data.

Codice:

SELECT PERIOD_DIFF(200905,200811);

 inserisci qui la descrizione dell'immagine

Risposta semplice data data di inizio come ins_frm e data di fine come 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

Divertiti :)))

Prova questo

SELECT YEAR(end_date)*12 + MONTH(end_date) - (YEAR(start_date)*12 + MONTH(start_date))

Questa query ha funzionato per me :)

SELECT * FROM tbl_purchase_receipt
WHERE purchase_date BETWEEN '2008-09-09' AND '2009-09-09'

Richiede semplicemente due date e recupera i valori tra di loro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top