2017-01-06 72 views
0

我使用史蒂夫卡斯公式在給定日期前一個月的第n周獲得一週的第n天。它工作的很好 - 但我真的不明白模數操作數在公式中的作用。有人可以解釋嗎?我試圖下面提供一些已知條件:史蒂夫卡斯公式在第n周的第n周發現第n天的公式模式解釋

declare @svcDate as datetime= '1/6/2017', @myN as tinyint=4, @myD as tinyint=1 

declare @ret datetime; 
declare @first datetime -- First of the month of interest (no time part) 
declare @nth tinyint -- Which of them - 1st, 2nd, etc. 
declare @dow tinyint -- Day of week we want - this server is set to - 1 sun, 2 mon, 3 tue, 4 wed, 5 thur, 6 fri, 7 sat 
set @first = dateadd(month,-1,datefromparts(year(@svcDate), month(@svcDate), 1)) --first of last month 
set @nth = @myN 
set @dow = @myD 
--Select @first 12/1/2016 

set @ret = @first + 7*(@nth-1) 
--select @ret 12/22/2016 Thurs 
--datepart(weekday,@ret)=5 

set @ret= @ret + (7 + @dow - datepart(weekday,@ret))%7 

if(@ret IS NULL) 
    set @ret='1/1/2017'; 

select @ret 

select 3%7 --returns 3 

select convert(decimal(18,2),3)/convert(decimal(18,2),7) -- returns 0.42857142857142857142 

回答

0

模數運算符(%)執行整數除法,並返回餘數。

如果你還記得小學數學。

23 divided by 7 

7進入23個三次,用2

23 = (7 * 3) + 2 

剩餘部分中的模函數僅返回整數除法後的餘數。


是的,我們希望表達3%7返回3

表達10%7也將返回3


EDIT

問:爲什麼公式中使用的模數運算符?

答:這是一個快捷方式,它消除了大量的條件檢查,如果它沒有被使用將是必需的。 (該公式可以在沒有模數操作的情況下執行,但是它可以在短時間內完成)。

在該公式中,從@dow減去weekday可能是負數天數。

而在公式中,我們不需要負數天。我們想要前進幾天,而不是倒退。

快捷方式是在減法結果上添加七天。這保證我們不會有負面的天數。但是,這種增加引入了另一個問題......如果減法產生了正數天,我們現在將有整整一週加上該天數。模數除以完整的星期,給我們留下一個0到6的整數,這是我們想要添加到@first的天數。


我們可以得到相同的結果,而不使用模數。爲此,我們將從@dow中減去weekday。如果減法的結果是負數,則加上7.

模數只是一個捷徑。該公式在所有情況下都加上7,然後在結果大於6的情況下減去7。

+0

您忽略回答實際問題:它在公式**中的作用**。它是否需要? –

+0

@PM:「模數運算符在公式**中做了什麼**與模運算符無處不在......」它會返回整數除法運算的其餘部分。我忽略回答的問題是一個沒有被問到的問題...... **「爲什麼公式中需要模數運算」**。我懷疑它在公式​​中,因爲'@ dow'和'weekday'的減法可能是負數。通過添加7然後進行模運算以消除整週,該公式會返回0到6範圍內的天數。 – spencer7593

+0

非常感謝Spencer7593。這對我來說很有意義,我真的很感謝你的非常詳細的答案。能夠獲得概念周圍的小灰色細胞。 – user1795131