2011-09-13 8 views
5

Sto scrivendo una piccola query in SQL e sto cercando teste con un problema che sembra come qualcuno deve aver incontrato prima. Sto cercando di trovare il numero di mesi tra due date. Sto usando un'espressione come ...Batting Datediff in SQL

DATEDIFF(m,{firstdate},{seconddate}) 

Tuttavia ho notato che questa funzione è conteggio dei tempi della data attraversa la soglia mensile. Nell'esempio ...

DATEDIFF(m,3/31/2011,4/1/2011) will yield 1 
DATEDIFF(m,4/1/2011,4/30/2011) will yield 0 
DATEDIFF(m,3/1/2011,4/30/2011) will yield 1 

Qualcuno sa come trovare i mesi tra due date più-così sulla base del tempo trascorso allora volte superato la soglia mensile?

+1

Interessante, non l'ho mai notato. – user937146

+1

Quanti giorni ci sono in un mese? vuoi indicare le coppie di date (2011-03-15, 2011-04-14), (2011-03-15, 2011-04-15), (2011-03-15, 2011-04-16), (2011 -01-28, 2011-02-2 8), (2011-01-28, 2011-03-01), (2012-01-29, 2012-02-28), (2012-01-29, 2012-02-29), (2012-01- 29, 2012-03-01), (2012-01-30, 2012-02-29), (2012-01-30, 2012-03-01) e così via.Ci tende ad essere una concentrazione sulla date in giro per la fine di febbraio negli anni bisestili e anni non bisestili, ma domande simili sorgono con altre date di fine mese, come (2011-05-31, 2011-06-30). –

risposta

1
DATEDIFF(m,{firstdate},ISNULL({seconddate},GETDATE())) - CASE 
                 WHEN DATEPART(d,{firstdate}) >= DATEPART(d,ISNULL({seconddate},GETDATE())) 
                 THEN 1 
                 ELSE 0 
+0

http://stackoverflow.com/questions/5131958/datediff-rounding – JBone

+0

L'originale ha '>' dove hai '> =', il che significa che se le parti al giorno sono uguali, il risultato di DATEDIFF saranno ancora diminuito di 1. Un'altra cosa è, calcolando la differenza di mesi tra le date come '' 2011-03-31' e 2011-06-30'. Questo metodo restituirà '2', poiché' 31' è effettivamente maggiore di '30'. Comunque giugno non può avere più di 30 giorni. Quindi "2 mesi" in questo caso, va bene? –

+1

Buoni punti. In questo caso non è eccessivamente critico tuttavia in certe situazioni potrebbe essere – JBone

2

Se si desidera trovare un numero teorico di mesi, perché non trovare la differenza in giorni, quindi dividere per 30 (eseguire il cast su FLOAT come richiesto). Oppure 30.5-ish forse - dipende da come si desidera gestire la durata variabile del mese per tutto l'anno. Ma forse questo non è un fattore nel tuo caso particolare.

1

Le seguenti dichiarazioni hanno lo stesso inizio e lo stesso fine. Queste date sono adiacenti e differiscono nel tempo di 0,0000001 secondo. La differenza tra la data di inizio e la fine di ogni istruzione incrocia un limite di calendario o temporale della sua parte di data. Ogni dichiarazione restituisce 1. ...
SELECT DATEDIFF (mese, '2005-12-31 23: 59: 59.9999999'
, '2006-01-01 00: 00: 00.0000000'); ....

(da DATEDIFF, sezione confini datepart). Se non sei soddisfatto da esso, probabilmente è necessario usare come unità di giorni, come proposto dal Martin Clayton

1

DATEDIFF è come questo in base alla progettazione. Quando si valuta una particolare misurazione del tempo (come mesi, o giorni, ecc.), Prende in considerazione solo quella misurazione e valori più alti, ignorando quelli più piccoli. Ti imbatterai in questo comportamento con qualsiasi misurazione del tempo. Ad esempio, se hai utilizzato DATEDIFF per calcolare giorni e una data pochi secondi prima di mezzanotte e un'altra data pochi secondi dopo la mezzanotte, riceverai una differenza di 1 giorno, anche se le due date erano solo alcune secondi a parte.

DATEDIFF ha lo scopo di dare una risposta alle domande di massima, in questo modo:

Domanda: quanti anni hai? Risposta: alcuni numeri interi. Non dici "Ho 59 anni, 4 mesi, 17 giorni, 5 ore, 35 minuti e 27 secondi". Dici solo "Ho 59 anni". Questo è anche l'approccio di DATEDIFF.

Se volete una risposta che è su misura per un certo significato contestuale (come il tuo figlio che dice: "Non sono 8! Sono 8 e 3 quarti !, o sono quasi 9!), Poi dovresti guardare la misurazione più piccola e approssimativa con quella. Quindi se sono mesi che cerchi, quindi fai un DATEDIFF in giorni o ore invece, e prova ad approssimare mesi, tuttavia sembra più rilevante per la tua situazione (forse vuoi risposte come 1-1/2 mesi, o 1,2 mesi, ecc.) utilizzando i tipi di logica CASE/IF-THEN

+0

Se hai compiuto 32 anni a dicembre e oggi a gennaio, non dici di aver 33 anni. Eppure DATEDIFF (ANNO) direbbe che lo sei. –

+0

@Andriy - era solo un esempio grossolano. Il punto era, non è rotto - è stato progettato per dare solo risposte approssimative. Ha un plus-o-minus (limiti di errore) di 1 (di qualsiasi misura tu stia utilizzando). – Chains

+0

Sì, sono d'accordo, che è di progettazione che funziona il modo in cui lo fa. E sono d'accordo sul fatto che c'è qualcosa di comune nel modo in cui sia DATEDIFF che le persone tendono a rispondere in modo approssimativo, con un numero intero approssimativo. È solo che DATEDIFF usa sempre le stesse regole, mentre le persone no. A volte facciamo il giro, come in * venti minuti alle cinque *, quando in realtà ha solo diciotto anni, e altre volte tendiamo a riportare un numero intero di unità complete, senza arrotondamenti, come con l'età in anni. E penso che sia quest'ultimo a volere l'OP, il modo di ottenere un risultato (anche un intero) * senza * arrotondare. –

Problemi correlati