Следующий код демонстрирует, как определить дату начала недели ISO (всегда понедельник) для двухмесячного окна дат. Оттуда просто вычесть одну неделю, чтобы получить начало предыдущей недели ISO.
with
Dates as (
-- Sample dates from the start of the current month ...
select Cast( DateAdd( day, 1 - Day( GetDate() ), GetDate() ) as Date ) as TheDate
union all
-- ... through two full months.
select DateAdd( day, 1, TheDate )
from Dates
where TheDate < Cast( DateAdd( month, 2, DateAdd( day, 1 - Day( GetDate() ), GetDate() ) ) as Date )
),
DatesWithISOWeeks as (
select TheDate, DatePart( iso_week, TheDate ) as ISOWeek,
-- Calculate the Monday on which the ISO week started regardless of @@DateFirst or language settings.
DateAdd( day, -( ( @@DateFirst + DatePart( weekday, TheDate ) - 2 ) % 7 ), TheDate ) as StartOfISOWeek
from Dates )
-- Output the results.
select TheDate, ISOWeek, StartOfISOWeek,
DateAdd( week, -1, StartOfISOWeek ) as StartOfPriorISOWeek
from DatesWithISOWeeks;
A where
условие сравнения TransactionDateTime
с границами - SARGable, т. Е. Он может получить выгоду от индекса на TransactionDateTime
:
where StartOfPriorISOWeek <= TransactionDateTime and TransactionDateTime < StartOfISOWeek
Обратите внимание, что сравнения <=
и <
, так что включается только одна неделя, а не восемь дней. Поскольку год указан в датах, никакого другого сравнения не требуется.
Также обратите внимание, что вычисления не зависят от настройки @@DateFirst
и текущего языка:
select Cast( DateAdd( day, -( ( @@DateFirst + DatePart( weekday, GetDate() ) - 2 ) % 7 ), Getdate() ) as Date ) as StartOfISOWeek;