2013-05-15 62 views
2

我試圖理解的代碼,有人錯誤地實現計算日期下列要求:使用T-SQL DATEADD和DATEDIFF函數

派生JE_ACCTNG_DT被設定爲等於前一個月的最後一天當前飼料創建和發送的當年。
例如,如果當前年份是2013年,JE_ACCTNG_DT將是基於所述季度進料被髮送以下內容:

  • JE_ACCTNG_DT = 2013年3月31日爲第一季度飼料上發送4/1/2013
  • JE_ACCTNG_DT = 2013年6月30日爲2013年7月1日上
  • JE_ACCTNG_DT = 2013年9月30日爲2013年10月1日上
  • JE_ACCTNG_DT = 12發送的第三季度進料送到第二季度飼料2013年1月1日發送的第四季度訂單/ 31/2013

我看到有人實現這樣的代碼,它似乎給在要求給出的例子正確的答案,如果日期時間的結果轉換爲日期數據類型(時間部分被丟棄)

DECLARE @FEED_DT datetime 

SET @FEED_DT = '4/1/2013' 
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)) 


SET @FEED_DT = '7/1/2013' 
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)) 
--2013-06-30 23:59:59.000 

SET @FEED_DT = '10/1/2013' 
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)) 
--2013-09-30 23:59:59.000 


SET @FEED_DT = '1/1/2014' 
select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)) 
--2013-09-30 23:59:59.000 

什麼是困惑我的是,DATEDIFF函數接受以下參數:一個日期部分和兩個日期

DATEDIFF(日期部分,開始日期,結束日期)

如果你在上面看到,該代碼設定日期部分「 m「,但當期望日期時,第二個參數爲零。

DECLARE @FEED_DT datetime = '4/1/2013' 
DECLARE @DateAddResult as int 

SET @DateAddResult = DATEDIFF(m,0,@FEED_DT) 
select @DateAddResult 
--1359 
select DATEADD(s,-1,DATEADD(mm, @DateAddResult,0)) 
--2013-03-31 23:59:59.000 

代碼真的在幹什麼?我會期待一個錯誤。它是否強迫0值約會?

我在想,要求真的應該是計算上一季度的最後一天。這是我的方式。

SELECT dateadd(day, -1, DATEADD(quarter,DATEDIFF(quarter,'1900/01/01', GETDATE()), '1900/01/01')) as FirstDayOfQuarter 
+3

0 = 1900-01-01。 –

+2

也請停止使用像mm和m這樣的懶惰速記。如果你是月份,輸入MONTH。 –

+1

約定m和mm。你是兩個意見合併給我我的答案。謝謝。 – ChadD

回答

2

有鑑於此:

select DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@FEED_DT),0)

讓我們把它一塊在同一時間...

DATEDIFF(m,0,@FEED_DT) 

...計算,具有全整數月數從日期值零(它被評估爲1-1-1900)過去到在日期時間字段@ FEED_DT中開始的日期值。比方說,這個值是@ElapsedMonthsSinceZero並更換該變量到原來的嵌套函數,贈送:

選擇DATEADD(S,-1,DATEADD(毫米,@ ElapsedMonthsSinceZero,0))

現在讓我們來評估此部分:

DATEADD(mm, @ElapsedMonthsSinceZero,0) 

這增加相同數目個月來的日期「零」,即1900年1月1日,它帶給你的日期@FEED_DT月份的第一天。從本質上講,我們迄今爲止所做的是計算從第0天開始已經過去的整個月數,截斷第1天以後的任何一天到本月。這給了我們@FirstDayOfFEED_DT。更換該到函數給了我們......

select DATEADD(s,-1,@FirstDayOfFEED_DT) 

現在我們已經有了日期@FEED_DT月份的第一天,減去1給了我們上月的最後一天。

我想我剛剛被拋出的差異,其中值0通過而不是日期。

1

假設您在新列中添加了一些日子,並且您有一個參數@date的存儲過程,並且您希望將當前日期添加到該參數並在幾天內獲得結果。

DateAdd(days,@date,Getdate())