CHill60
Вы можете использовать CASE в бите добавления например
declare @start date = '2020-01-01'
declare @end date = dateadd(dd, 10, @start)
declare @daystoadd int = 3
;WITH sampledatelist AS
(
SELECT @start AS datum
UNION ALL
SELECT dateadd(DAY, 1, datum)
FROM sampledatelist
WHERE dateadd(day, 1, datum) < @end
)
CTE выше просто генерирует некоторые даты. Вот запрос, который находит следующий рабочий день
select datum, -- the date we're trying to add to
DATEADD(DD, @daystoadd, datum)
AS JustAddedOn, -- as it says on the tin
DATEPART(DW, DATEADD(DD, @daystoadd, datum))
AS DayOfJustAddedOn, -- what day of the week would that be
CASE WHEN DATEPART(DW, DATEADD(DD, @daystoadd, datum)) = 7 THEN
DATEADD(DD, @DAYSTOADD + 2, DATUM) -- Handle Saturdays
WHEN DATEPART(DW, DATEADD(DD, @daystoadd, datum)) = 1 THEN
DATEADD(DD, @DAYSTOADD + 1, DATUM) -- Handle Sundays
ELSE
DATEADD(DD, @daystoadd, datum) -- otherwise use the JustAddedOn date
END as calcdate
from sampledatelist
что дает результаты
datum JustAddedOn Day calcdate
2020-01-01 2020-01-04 7 2020-01-06
2020-01-02 2020-01-05 1 2020-01-06
2020-01-03 2020-01-06 2 2020-01-06
2020-01-04 2020-01-07 3 2020-01-07
2020-01-05 2020-01-08 4 2020-01-08
2020-01-06 2020-01-09 5 2020-01-09
2020-01-07 2020-01-10 6 2020-01-10
2020-01-08 2020-01-11 7 2020-01-13
2020-01-09 2020-01-12 1 2020-01-13
2020-01-10 2020-01-13 2 2020-01-13
Предостережения
- Проверьте свои настройки локализации для того, что представляет собой уик-энд для вашей части мира!
- Это не относится к национальным праздникам и т. д
Кстати, лично я очень не люблю преобразовывать даты в строки только для того, чтобы добавить время (это просто моя вещь). Я предпочитаю добавлять необходимое количество часов (или в данном случае секунд) к "началу" рассматриваемого дня, например
declare @starttime INT = DATEDIFF(SECOND,0,CAST('08:00:00' AS datetime)) -- End Time will be 1 second earlier
select dateadd(second, @starttime, dateadd(dd, datediff(dd, 0, dateadd(day, -5, current_timestamp)), 0)) as [Start Date],
dateadd(second, @starttime - 1, dateadd(dd, datediff(dd, 0, dateadd(day, -4, current_timestamp)), 0)) as [End Date]
Наконец, если бы я много сравнивал даты с рабочими днями и праздниками, я бы построил таблицу дат, содержащую все полезные вещи, такие как дата, день недели, квартал, финансовый период, рабочий день и т. д., а затем использовал бы эту ссылку в других запросах, присоединяясь к дате. Вы даже можете иметь заранее рассчитанную колонку "следующий рабочий день"