我目前正在尝试编写一个存储过程,可以计算日期作为参数传递的双周期。
业务逻辑:今年的第一个星期一是每两周一次的第一天。
例如2010年:
period period_start period_end
1 2010-01-04 2010-01-17
2 2010-01-18 2010-01-31
3 2010-02-01 2010-02-14
....
26 2010-12-20 2011-01-02
通过今天的2010-12-31日期将返回26,2010-12-20和2011-01-02。怎么做到这一点?
答案 0 :(得分:2)
-- 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所说,根据你的工作,你可能最好建立和使用某种形式的双周期查询表,特别是如果你需要妥善处理那些早期的日期。
答案 1 :(得分:1)
您可以创建一个函数来获取一年的第一个星期一。这样的事情应该有效:
CREATE FUNCTION dbo.FirstMonday(@Year VARCHAR(4))
RETURNS DATE
AS
BEGIN
DECLARE @Return DATE;
WITH Dates AS
(
SELECT CONVERT(DATE,@Year+'0101') AS DateVal
UNION ALL
SELECT DATEADD(d, 1, DateVal) AS DateVal
FROM Dates
WHERE DATEADD(d, 1, DateVal) < DATEADD(m, 1, @Year+'0101')
)
SELECT @Return = MIN(DateVal)
FROM Dates
WHERE DATENAME(WEEKDAY,DateVal) = 'Monday'
RETURN @Return
END