史密斯卡斯公式的模数解释在第n个星期找到第n周的第n天

时间:2017-01-06 17:15:30

标签: sql modulus

我使用史蒂夫卡斯公式来获得给定日期的上个月第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

1 个答案:

答案 0 :(得分:0)

模数运算符(%)执行整数除法,并返回余数。

如果你还记得小学数学。

23 divided by 7

7进入23三次,其余为2

23 = ( 7 * 3 ) + 2

模数函数只返回整数除法后的余数。

是的,我们希望表达式3%7返回3

表达式10%7也将返回3

修改

问:为什么在公式中使用模数运算符?

答:这是一种快捷方式,可以消除许多条件检查,如果不使用则需要这些检查。 (该公式可以在没有模数运算的情况下执行,但它的使用时间要短得多。)

在公式中,从weekday减去@dow可能是负天数。

在公式中,我们不想要负天数。我们想要向前推进几天,而不是倒退。

快捷方式是在减法结果中添加七天。这保证了我们不会有负数天。但是这个添加引入了另一个问题......如果减法导致正天数,我们现在有一整周加上那个天数。模数除法消除整周,给我们留下0到6范围内的整数,即我们想要添加到@first的天数。

我们可以在不使用模数的情况下得到相同的结果。为此,我们会从weekday减去@dow。如果减法的结果是否定,则添加7。

模数只是一个捷径。公式在所有情况下都会增加7,然后在结果大于6的情况下减去7。