This is an old question. But I'm sure publishing the best solution is worth it.
-- 0 = 1st Mon, 1 = 1st Tue, 2 = 1st Wed, ..., 5 = 1st Sat, 6 = 1st Sun -- 7 = 2nd Mon, 8 = 2nd Tue, ... declare @NextDayID int = 0, @Date date = getdate() select cast (cast ( -- last Monday before [Date] inclusive, starting from 1900-01-01 datediff (day, @NextDayID % 7, @Date) / 7 * 7 -- shift on required number of days + @NextDayID + 7 as datetime) as date)
This solution is an improved solution by @Bogdan Sahlean. It can run @NextDayID, which is greater than 6. So, for example, you can find the second Monday from today.
The following query shows that my solution is working correctly.
select [Date] , convert (char(5), [0], 10) as Mon1 , convert (char(5), [1], 10) as Tue1 , convert (char(5), [2], 10) as Wed1 , convert (char(5), [3], 10) as Thu1 , convert (char(5), [4], 10) as Fri1 , convert (char(5), [5], 10) as Sat1 , convert (char(5), [6], 10) as Sun1 , convert (char(5), [7], 10) as Mon2 , convert (char(5), [8], 10) as Tue2 from ( select [Date], NextDayID , cast (cast ( datediff (day, NextDayID % 7, [Date]) / 7 * 7
Result:
Date | Mon1 | Tue1 | Wed1 | Thu1 | Fri1 | Sat1 | Sun1 | Mon2 | Tue2 -----------+-------+-------+-------+-------+-------+-------+-------+-------+------ 2018-05-14 | 05-21 | 05-15 | 05-16 | 05-17 | 05-18 | 05-19 | 05-20 | 05-28 | 05-22 2018-05-15 | 05-21 | 05-22 | 05-16 | 05-17 | 05-18 | 05-19 | 05-20 | 05-28 | 05-29 2018-05-16 | 05-21 | 05-22 | 05-23 | 05-17 | 05-18 | 05-19 | 05-20 | 05-28 | 05-29 2018-05-17 | 05-21 | 05-22 | 05-23 | 05-24 | 05-18 | 05-19 | 05-20 | 05-28 | 05-29 2018-05-18 | 05-21 | 05-22 | 05-23 | 05-24 | 05-25 | 05-19 | 05-20 | 05-28 | 05-29 2018-05-19 | 05-21 | 05-22 | 05-23 | 05-24 | 05-25 | 05-26 | 05-20 | 05-28 | 05-29 2018-05-20 | 05-21 | 05-22 | 05-23 | 05-24 | 05-25 | 05-26 | 05-27 | 05-28 | 05-29
This decision is independent of @@datefirst .