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