Примечание: Любой ответ, который начинается с предположения, что год 2011, также может принимать статическую первую дату, т. Е. Заменить @firstMon в моем последнем запросе ниже только статической датой '20101227' .
SET DATEFIRST 1
declare @targetYear int
declare @targetWeek int
select @targetYear = 2011, @targetWeek = 23
declare @firstMon datetime
set @firstMon = dateadd(d,1-datepart(dw, right(@targetYear,4)+'0101'),right(@targetYear,4)+'0101')
select
MonOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon),
SunOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon+6)
И реальный, последний запрос, который возвращает Mon / Sun со значением NULL, если он не существует на этой неделе, например, Mon из частичной недели или Sun из частичной недели 53
;with tmp(Mon, Sun) as (
select
MonOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon),
SunOfTargetWeek = dateadd(week, @targetWeek-1, @firstMon+6)
)
select
RealMonday = case when Year(Mon)=@targetYear then Mon end,
RealSunday = case when Year(Sun)=@targetYear then Sun end
from tmp
Для заявления GBN о том, что этот ответ неправильный (в пределах его ответа), я представлю ниже подтверждение правильности
Я превратил код в функцию.
CREATE function dbo.getMonSunForWeek(@targetYear int, @targetWeek int)
returns table as return
with pre(firstMon) as (
select dateadd(d,1-datepart(dw, right(@targetYear,4)+'0101'),right(@targetYear,4)+'0101'))
, tmp(Mon, Sun) as (
select
dateadd(week, @targetWeek-1, firstMon),
dateadd(week, @targetWeek-1, firstMon+6)
from pre
)
select
Mon, Sun,
RealMonday = case when Year(Mon)=@targetYear then Mon end,
RealSunday = case when Year(Sun)=@targetYear then Sun end
from tmp
GO
И ниже я представляю ВЕСЬ диапазон лет и недель (1-53) для лет с 1950 по 2047 год. В случае КАЖДЫЙ ОДИН , когда был определен понедельник / воскресенье, и работая в обратном направлении, используя DATEPART(week)
, SQL Server соглашается с нумерацией недель из функции.
set datefirst 1;
select
[Year] = years.number,
[Week] = weeks.number,
[Mon] = fun.realmonday,
[Sun] = fun.realsunday,
[WeekX] = isnull(datepart(week, fun.realmonday), datepart(week, fun.realsunday)),
[MonX] = fun.Mon,
[SunX] = fun.Sun
from master..spt_values years
inner join master..spt_values weeks on weeks.type='P' and weeks.number between 1 and 53
cross apply dbo.getMonSunForWeek(years.number, weeks.number) fun
where years.type='P' and years.number between 1950 and 2047
order by [year], [Week]
Выход на смену 2005-2006 гг.
when including prior/next year
Year Week Mon-of-week Sun-of-week datepart(week) Mon -and- Sun
2005 52 2005-12-19 2005-12-25 52 2005-12-19 2005-12-25
2005 53 2005-12-26 NULL 53 2005-12-26 2006-01-01
2006 1 NULL 2006-01-01 1 2005-12-26 2006-01-01
2006 2 2006-01-02 2006-01-08 2 2006-01-02 2006-01-08