@ Ламак выполнил сложную часть, выяснив первый понедельник в году (голосование поднято).Я немного изменил его подпрограмму, чтобы получить значение даты и времени, например:
-- Return first Monday for the year being passed in
CREATE FUNCTION dbo.FirstMonday (@TargetDay datetime)
RETURNS DATE
AS
BEGIN
DECLARE @Return DATE
-- Set to first of its year
SET @TargetDay = dateadd(dd, -datepart(dayofyear, @TargetDay) + 1, @TargetDay)
;WITH Dates AS
(
SELECT @TargetDay AS DateVal
UNION ALL
SELECT DATEADD(d, 1, DateVal) AS DateVal
FROM Dates
WHERE DATEADD(d, 1, DateVal) < DATEADD(m, 1, @TargetDay)
)
SELECT @Return = MIN(DateVal)
FROM Dates
WHERE DATENAME(WEEKDAY,DateVal) = 'Monday'
RETURN @Return
END
GO
-- Test it
print dbo.FirstMonday(getdate())
print dbo.FirstMonday('Jan 1, 2010')
Оттуда это просто некоторая арифметика даты и времени:
DECLARE
@FirstMonday datetime
,@TargetDay datetime
,@BiWeek int
SET @TargetDay = getdate()
--SET @TargetDay = 'Jan 17, 2010'
-- Get the first Monday
SET @FirstMonday = dbo.FirstMonday(@TargetDay)
-- Calculate the bi-weekly period
SET @BiWeek = datediff(dd, @FirstMonday, @TargetDay) / 14
-- Print results
PRINT @BiWeek + 1
PRINT dateadd(dd, @BiWeek * 14, @FirstMonday)
PRINT dateadd(dd, @BiWeek * 14 + 13, @FirstMonday)
-- Or return them as a dataset
SELECT
@BiWeek + 1 Period
,dateadd(dd, @BiWeek * 14, @FirstMonday) PeriodStart
,dateadd(dd, @BiWeek * 14 + 13, @FirstMonday) PeriodEnd
Это не работает, когда вы выбираете деньгод, который выпадает до первого понедельника, так как он возвращает первый двухнедельный период после этой даты.(Или это не получается? Вы не указали, какой период подходит для таких дат ...:)
Однако, как говорит @HLGEM, в зависимости от того, что вы делаете, вам, вероятно, лучше строить и использоватьнекоторая форма таблицы поиска раз в две недели, особенно если вам нужна правильная обработка этих ранних дат.