Вот немного «волшебный» способ вычисления значения, которое не зависит от каких-либо конкретных настроек сервера, таких как datefirst
.Вероятно, не сразу очевидно, как это работает:
WHERE DOC_DATE = dateadd(day,datediff(day,'20150316',getdate()),
CASE WHEN DATEPART(weekday,getdate()) = DATEPART(weekday,'20150330')
THEN '20150313'
ELSE '20150315' END)
В первой строке мы вычисляем количество дней, прошедших с некоторой произвольной даты.Я выбрал день в марте 2015 года для использования в качестве базовой даты.
Во второй строке задается вопрос о том, какой сегодня день недели, и совпадает ли он с каким-то произвольным «известным хорошим» понедельником.Просто взять одно значение и сравнить его с 2
, зависит от того, какое у вас значение DATEFIRST
, поэтому я предпочитаю не записывать это.
В третьей строке мы решаем, что делать, если это понедельник - ядать дату, которая за 3 дня до моей произвольной даты выше.Если это не был понедельник, мы выбираем день раньше.
Сложив все это вместе, когда мы добавляем разницу в днях от произвольной даты обратно к одной из этих двух дат из строк 3 и 4, она имеетэффект смещения даты назад на 1 или 3 дня.
Это может быть странная структура, если вы не знакомы с ней - но объединение dateadd
/ datediff
и использование отношениймежду произвольной датой и другими датами, вычисленными по ней, может быть полезным для выполнения всех видов вычислений.Аналогичная структура может использоваться для вычисления, например, последнего дня месяца 15 месяцев назад, используя просто dateadd
/ datediff
, произвольную дату и другую дату с правым смещением от первого:
SELECT DATEADD(month,DATEDIFF(month,'20010101',GETDATE()),'19991031')
Однако, как я уже сказал в комментарии, обычно выполнение такого рода действий является лишь небольшим шагом от необходимости правильно моделировать рабочие дни вашей организации, после чего вы, как правило, захотите представить таблицу календаря.На одну строку в день предварительно рассчитанный календарь на 20 лет (при необходимости корректируемый по мере изменения бизнеса) по-прежнему меньше 10000 строк.