如何在SQL Server中每年每月获得两周一次的日期?

时间:2017-03-28 01:03:15

标签: sql sql-server tsql

当我设定开始年份和结束年份时,我正试图生成每两周一次的日期。

DECLARE @StartYear DATETIME
DECLARE @EndYear DATETIME

SET @StartYear = '01/01/2017'
SET @EndYear = '12/31/2017'

T-SQL应该计算每两周一次的日期,例如:03/15/2017和03/30/2017是发薪日。

此外,如果日期在星期六和星期日,那么它将生成到第一个星期五的日期。

希望有人可以帮助我。或者有人愿意分享他/她关于此的知识和公式。

更新:我的预期结果如下:

当我进入01/01/2017时,它会自动生成每15天。

示例:

@StartYear: 01/01/2017

结果应该是:

DatesBiweeklyPerMonthInAYear
-------------------------------
01/13/2017 (since the 15th day falls on sunday)
01/30/2017
02/15/2017
02/28/2017 (since no 30th day)

如果第15天落在太阳或坐着它将在特定周的星期五落下。 所以...直到今年年底。

这可以实现吗?或不?

谢谢!

2 个答案:

答案 0 :(得分:2)

这是一个开始。你必须调整逻辑才能得到你想要的结果。

DECLARE @MinDate DATE = '20170101', 
        @MaxDate DATE = '20171231'; 
DECLARE @date DATE; 
DECLARE @counter INT = 0; 
DECLARE my_cursor CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY FOR 
  SELECT TOP (Datediff(day, @MinDate, @MaxDate) + 1) Date = 
  Dateadd(day, Row_number() 
                 OVER( 
                   ORDER 
  BY a.object_id) - 1, @MinDate) 
  FROM   sys.all_objects a 
         CROSS JOIN sys.all_objects b; 

OPEN my_cursor 

FETCH next FROM my_cursor INTO @date 

WHILE @@FETCH_STATUS = 0 
  BEGIN 
      IF( @counter = 15 ) 
        BEGIN 
            PRINT @date -- here is where you get the 15th date
            SET @counter = 0 
        END 
      SET @counter = @counter + 1 
      FETCH next FROM my_cursor INTO @date 
  END 

CLOSE my_cursor 

DEALLOCATE my_cursor 

答案 1 :(得分:2)

您的业务规则并非100%明确。

我认为可以有多个正确的结果。

在一个地方它是硬编码的,因为我想100%确定要求。 我没有使用cursor.Its只有24个循环。

declare @StartYear datetime='2017-01-01'
declare @endYear datetime ='2017-12-31'

declare @gap int =14 --Bimonthly means gap of 14 days or 15 days whatever

;With CTE as
(
select dateadd(day,@gap, @StartYear) Bimonthly
,1 rn

UNION ALL

select  
case 

when (rn+1)%2=0 and datename(m, Bimonthly)='February' THEN
      '2017-02-28'
      when (rn+1)%2=0 and datename(m, Bimonthly)!='February' 

then dateadd(day,@gap, Bimonthly)
else 
dateadd(day,@gap, dateadd(month, datediff(month,0,dateadd(month,1,Bimonthly)),0))
END
,rn+1
from cte
where rn< (datediff(month,@StartYear, @endYear)+1)*2

)
select 
case WHEN datename(dw, Bimonthly)='Saturday' THEN
      dateadd(day,-1, Bimonthly) 
      WHEN datename(dw, Bimonthly)='Sunday' THEN 
      dateadd(day,-2, Bimonthly) 
     else 
      Bimonthly
     end 

     ,rn

from cte