SQL - получить конкретные даты на основе рабочей недели

Нам нужно определить конкретные даты, между которыми будут извлечены данные.

Например, транзакции, которые происходят в первый день месяца, проводятся в систему учета 2-го числа, а транзакции, которые происходят в последний день месяца, проводятся в систему учета 1-го числа следующего месяца.

Поэтому, в то время как обычно я мог просто взять все записи, где месяц - 10 октября, теперь мне нужно извлечь записи, где дата находится между 2 октября и до 2 ноября.

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

Declare @EarliestDate varchar(8), @SQL NVARCHAR(1000), @sDate varchar(8)

-- get data for the last 3 months
SET @EarliestDate= CAST(DATEPART(YEAR,DATEADD(m,-3, getdate())) AS VARCHAR(4)) 
    + RIGHT('00' + CAST(DATEPART(mm, DATEADD(m,-2, getdate())) AS varchar(2)), 2)+ '02' 

Теперь мне нужно проверить, является ли 1 ноября выходным, и если это так, используйте дату следующего понедельника.

Я запустил приведенный ниже код, но не могу заставить его работать должным образом:

Declare @LatestDate datetime

set @LatestDate = '01/11/2014'

if datepart(dw,@LatestDate) in (1,7)
Begin
    set @LatestDate = DATEADD(d,1,@LatestDate ) 
End

Пожалуйста, вы можете показать мне, где я иду не так? В идеале он должен работать круглый год, независимо от того, какой это год, и всегда получать первый рабочий день после 1-го числа месяца.

2 ответа

Решение

Я рекомендую вам сгенерировать таблицу дат из сценария в разделе " Создание и заполнение в измерении дат для хранилища данных" и использовать ее, чтобы выяснить, когда наступит ваш следующий рабочий день. Для своих собственных целей я отбросил все колонки Великобритании и фискальные колонки - хотя они могут быть полезны для вас Вы также можете добавить свои собственные праздники и присоединиться непосредственно к запросу вместо создания определенной функции.

Тогда вы можете просто сделать следующее:

DECLARE @LatestDate date

SET @LatestDate = '01/11/2014'

SELECT @LatestDate = MIN([Date]) FROM DimDate
WHERE [Date] >= @LatestDate
AND IsWeekday = 1 AND IsHoliday = 0

PRINT @LatestDate

Здесь нужно учесть несколько вещей:

Используйте строку

Set Dateformat dmy;

Чтобы обеспечить преобразование строки в дату в правильном формате даты (в данном случае не по-американски).

Убедитесь, что (1,7) являются правильными датами выходных для конкретного сервера. Вы можете проверить это, запустив:

Select @@Datefirst

Который скажет вам, какой день недели первый. По умолчанию установлено значение 7 (воскресенье), что работает для приведенного ниже примера. Вы можете изменить это при необходимости:

http://msdn.microsoft.com/en-gb/library/ms181598.aspx

Об этом следует знать, если вы планируете перенести код на другой сервер.

Ваш код должен добавить 1 для воскресенья и 2 для субботы:

-- Saturday
if datepart(dw,@LatestDate) = (1)
    set @LatestDate = DATEADD(dd,1,@LatestDate);

-- Sunday
if datepart(dw,@LatestDate) = (7)
    set @LatestDate = DATEADD(dd,2,@LatestDate);

Использование измерения даты, в то время как добавление небольших начальных издержек проще, эффективнее, а также более надежно (т.е. @@Datefirst независимо). Вы также можете легко заполнить праздничные дни и принять их во внимание. Существует много сценариев для заполнения таблицы измерения даты, например:

http://www.codeproject.com/Articles/647950/Create-and-Populate-Date-Dimension-for-Data-Wareho

Другие вопросы по тегам