2011-09-13 45 views
5

我在SQL中寫了一個小查詢,並且碰到一個問題,它似乎是某個人必須碰到的問題。我正在嘗試查找兩個日期之間的月數。我使用的表達式如...在SQL中與Drateiff作戰

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

但是我注意到這個函數計算日期跨越每月閾值的時間。在示例...

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 

有誰知道如何找到更因此基於兩個日期之間的幾個月後時間的推移,然後次了每月門檻?

+1

有趣的是,我從來沒有注意到它是這樣做的 – user937146

+1

一個月中有多少天?你想給出日期對(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- (2012-01-30,2012-02-29),(2012-01-30,2012-03-01)等。(閏年和非閏年)的日期往往集中在2月底左右,但類似的問題與其他月末日期(2011-05-31,2011-06-30)相似。 –

回答

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

原來已經有'>'你有'> ='的地方,這意味着如果每天的部分相等,DATEDIFF的結果仍然會降低另一件事是,計算「2011-03-31」和「2011-06-30」之間的日期差異。這個方法會返回'2',因爲'31'的確大於'30'。但六月不能超過30天。那麼在這種情況下'2個月'好嗎? –

+1

好點。在這種情況下,它並不過分嚴格,但是在某些情況下,它可能是 – JBone

2

如果你想找到一些名義上的月數,爲什麼不找天差異,然後除以30(根據需要投到FLOAT)。也許30.5歲 - 取決於你想如何處理全年可變月份長度。但也許這不是你特定情況下的一個因素。

1

以下語句具有相同的startdate和相同的endate。這些日期相鄰,並且在時間上有差異.0000001秒。每條語句中的開始日期和結束日期之間的差異跨越其日期部分的一個日曆或時間邊界。每個語句返回1. ...
SELECT DATEDIFF(month,'2005-12-31 23:59:59.9999999'
,'2006-01-01 00:00:00.0000000'); ....

(從DATEDIFF,部分日期部分邊界)。如果你沒有被它滿意,你可能需要使用天爲單位所提議的馬丁·克萊頓

1

DATEDIFF是這樣的設計。在評估特定的時間測量(如月,日等)時,只考慮測量值和較高的值 - 忽略較小的值。任何時間測量都會遇到這種情況。例如,如果您使用DATEDIFF計算天數,並且在午夜前幾秒鐘有一個日期,而在午夜幾秒鐘後有另一個日期,那麼即使兩個日期僅爲幾天,您也會得到「1」天的差異相隔數秒。

DATEDIFF是爲了給一個粗略的答案的問題,像這樣的:

問題:有多少歲是你嗎? 答案:一些整數。你不會說「我59歲,4個月,17天,5小時,35分27秒」。你只是說「我59歲」。這也是DATEDIFF的做法。 (如你的兒子說:「我不是8!我是8和3分之一!,或者我是差不多 9!),那麼,如果你想要一個適合某些上下文含義的答案你應該看看下一個最小的測量值並且與它近似,所以如果它是幾個月後,那麼可以在幾天或幾小時內做一個DATEDIFF,然後嘗試接近幾個月,但它看起來與你的情況最相關(也許你想要回答如1-1/2個月或1.2個月等)使用CASE/IF-THEN種邏輯

+0

如果你在12月和今天的1月份變成了32,那麼你不會說你是33.然而DATEDIFF(YEAR)會說你是。 –

+0

@Andriy--這只是一個很好的例子。問題是,它沒有被破壞 - 它只是爲了給出粗略的答案。它有1(無論你使用什麼測量)的加號或減號(誤差界限)。 – Chains

+0

是的,我同意,它的設計是按照它的工作方式進行的。我同意DATEDIFF和人們都傾向於粗略地回答一些常見問題,其中大概是整數。只是DATEDIFF總是使用相同的規則,而人們卻不這樣做。有時候我們會圍繞着,比如在*五十分鐘的20分鐘內,實際上只有十八分鐘,而在其他時候,我們傾向於報告一整套完整的單位,沒有任何舍入,就像年齡一樣。我認爲OP是想要的是後者,也就是獲得結果的方式(也是一個整數),而不是舍入。 –