这是一个老问题。但我确信发布更好的解决方案值得。
-- 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)
该解决方案是@Bogdan Sahlean 的改进解决方案。它可以操作大于 6 的@NextDayID。例如,您可以找到从今天开始的第 2 个星期一。
以下查询显示我的解决方案工作正常。
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 -- last Monday before [Date] inclusive, starting from 1900-01-01
+ NextDayID + 7 -- shift on required number of days
as datetime) as date) as NextDay
from (
select datefromparts (2018, 5, dt) as [Date]
from (values(14),(15),(16),(17),(18),(19),(20))t_(dt)
) d
cross join (values(0),(1),(2),(3),(4),(5),(6),(7),(8))nd(NextDayID)
) t
pivot (
min (NextDay) for NextDayID in ([0], [1], [2], [3], [4], [5], [6], [7], [8])
) pvt
结果:
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
此解决方案不依赖于@@datefirst
.