Выбор строк с датой и временем, в которые прошла полная неделя ISO - PullRequest
0 голосов
/ 10 мая 2019

Мне нужно выбрать строки из таблицы с датой и временем в течение всей прошедшей недели ISO. Таблица представляет собой ежедневную таблицу транзакций, которую я использую для агрегирования чисел с неделями ISO. Если я сегодня агрегирую таблицу, агрегация на этой неделе будет основана только на данных транзакций за текущую неделю, которая еще не завершилась. Итак, на момент написания статьи текущий год и неделя это 2019-19. Я хотел бы вычесть одну неделю, чтобы были получены только строки с годом и неделей 2019-18 или ранее.

Я использую Microsoft SQL Server, и поэтому мне не хватает функции MySQL YEARWEEK, которая, как мне кажется, облегчит эту задачу. По сути, я пытаюсь сделать то, что, по моему мнению, SELECT * FROM TableA WHERE YEARWEEK(TransactionDateTime) <= YEARWEEK(DATEADD(week, -1, MAX(TransactionDateTime))) сделает.

Ответы [ 2 ]

0 голосов
/ 10 мая 2019

Следующий код демонстрирует, как определить дату начала недели 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;
0 голосов
/ 10 мая 2019

Попробуйте это-

SELECT * FROM TableA 
WHERE YEAR(TransactionDateTime) = 2019
AND  DATEPART(WEEK,TransactionDateTime) = DATEPART(WEEK,GETDATE()) - 1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...