SQL Server。获得每两周一次的存储过程

时间:2010-12-31 14:26:05

标签: sql-server-2008 stored-procedures date

我目前正在尝试编写一个存储过程,可以计算日期作为参数传递的双周期。

业务逻辑:今年的第一个星期一是每两周一次的第一天。

例如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。怎么做到这一点?

2 个答案:

答案 0 :(得分:2)

@Lamak做了很大的努力,弄清楚了今年的第一个星期一(upvoted)。我修改了他的例程以获取日期时间值,如下所示:

--  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