2017-01-06 13 views
0

Я использую формулу Стива Касса, чтобы получить 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.


РЕДАКТИРОВАТЬ

В: Почему модуль оператора, используемый в формуле?

A: Это ярлык, который устраняет множество условных проверок, которые потребуются, если они не были использованы. (Формула может быть выполнена без операции модуля, но она намного короче с ней.)

В формуле вычитание weekday от @dow потенциально может быть отрицательным числом дней.

И в точке формулы мы не хотим отрицательного количества дней. Мы хотим двигаться вперед несколько дней, а не назад.

Ярлык должен добавить семь дней к результату вычитания. Это гарантирует нам, что у нас не будет отрицательного количества дней. Но это дополнение вводит еще одну проблему ... если бы вычитание привело к положительному числу дней, теперь у нас будет полная неделя плюс это количество дней. Деление модуля исключает полные недели, оставляет нас с целым числом в диапазоне от 0 до 6, количеством дней, которое мы хотим добавить в @first.


Мы можем получить тот же результат без использования модуля. Для этого мы вычитаем weekday с @dow. Если результатом вычитания является отрицательный, затем добавить 7.

Модуль является просто ярлыком. Формула добавляет 7 во всех случаях, а затем вычитает обратно 7 в случаях, когда результат больше 6.

+0

Вы пренебрегли ответом на фактический вопрос: что он делает ** в формуле **. Нужно ли вообще? –

+0

@PM: «что [оператор модуля] ** в формуле **» - это то же самое, что оператор модуля всюду ...он возвращает оставшуюся часть операции целочисленного деления. Вопрос, на который я забыл ответить, был вопросом, который не задавался ... ** «Зачем нужна модульная операция в формуле» **. Я подозреваю, что это в формуле, потому что вычитание '@ dow' и' weekday' потенциально отрицательно. Добавив 7, а затем выполнив операцию модуля для устранения полных недель, формула возвращает число дней в диапазоне от 0 до 6. – spencer7593

+0

Большое спасибо, Spencer7593. Это имеет смысл для меня о сокращении, и я искренне ценю ваш очень подробный ответ. Смогла получить маленькие серые клетки вокруг концепции. – user1795131

 Смежные вопросы

  • Нет связанных вопросов^_^