求算法:一段时间段内的星期几到星期几的集合

假设时间段为2009-04-01到2009-04-30.
我想得到这段时间内,每逢周一至周二的日期,要返回的结果集可以为DataTable(两列-周二日期和周三日期),或是二维数组(周二日期,周三日期)

另外:因为4月1号是星期三,所以周一至周二只有如下数据:
周一          周二
2009-04-06  2009-04-07
2009-04-13  2009-04-14
2009-04-20  2009-04-21
2009-04-27  2009-04-28

即,超过起始日期的星期几不算在内.

--2000
DECLARE @start_dt DATETIME,@end_dt DATETIME;
SELECT @start_dt='2009-04-01',@end_dt='2009-04-30';

SELECT
   
MAX(CASE WHEN [weekday]=1 THEN dt END) AS 周一,
   
MAX(CASE WHEN [weekday]=2 THEN dt END) AS 周二
FROM (
  
SELECT
      
DATEADD(day,number,@start_dt) AS dt,
       (
DATEPART(weekday,DATEADD(day,number,@start_dt))+@@DATEFIRST-1)%7 AS [weekday],
      
DATEPART(week,DATEADD(day,number,@start_dt)) AS [week]
  
FROM master.dbo.spt_values AS A
  
WHERE A.type='p'
      
AND DATEADD(day,number,@start_dt)<=@end_dt
      
AND (DATEPART(weekday,DATEADD(day,number,@start_dt))+@@DATEFIRST-1)%7 IN(1,2)
)
AS A
GROUP BY [week]


/*
周一                      周二
----------------------- -----------------------
2009-04-06 00:00:00.000 2009-04-07 00:00:00.000
2009-04-13 00:00:00.000 2009-04-14 00:00:00.000
2009-04-20 00:00:00.000 2009-04-21 00:00:00.000
2009-04-27 00:00:00.000 2009-04-28 00:00:00.000

(4 行受影响)

*/

declare @bt datetime,@et datetime
select @bt='2009-04-01',@et='2009-04-30'
select a.dt 周一,b.dt 周二
from
   (
    
select dt=dateadd(dd,number,@bt) from master..spt_values where type='p' and number<=datediff(dd,@bt,@et) and datepart(w,dateadd(dd,number,@bt)+@@datefirst-1)=1
   ) a,
   (
    
select dt=dateadd(dd,number,@bt) from master..spt_values where type='p' and number<=datediff(dd,@bt,@et) and datepart(w,dateadd(dd,number,@bt)+@@datefirst-1)=2
   ) b
where a.dt+1=b.dt

/*
周一                      周二
----------------------- -----------------------
2009-04-06 00:00:00.000 2009-04-07 00:00:00.000
2009-04-13 00:00:00.000 2009-04-14 00:00:00.000
2009-04-20 00:00:00.000 2009-04-21 00:00:00.000
2009-04-27 00:00:00.000 2009-04-28 00:00:00.000

(4 行受影响)
*/

CREATE PROC
    p
@start_dt DATETIME,
   
@end_dt DATETIME,
   
@weekdays VARCHAR(20)
AS
   
DECLARE @sSQL NVARCHAR(4000);
   
DECLARE @columns NVARCHAR(1000)
   
SELECT @sSQL='',@columns='';
   
   
CREATE TABLE #weekday_table(ID TINYINT IDENTITY,[weekday] INT);
   
INSERT #weekday_table([weekday])
       
SELECT
           
SUBSTRING(@weekdays,number,
                       
CHARINDEX(',',@weekdays+',',number)-number)
       
FROM master.dbo.spt_values AS A
       
WHERE A.type='p'
           
AND number BETWEEN 1 AND LEN(@weekdays)
           
AND SUBSTRING(','+@weekdays,number,1)=',';
           
   
SELECT
       
@columns=@columns+N',MAX(CASE WHEN [weekday]='+ RTRIM([weekday])+N' THEN dt END) AS [周'+
                           
CASE [weekday]
                               
WHEN 0 THEN N''
                               
WHEN 1 THEN N''
                               
WHEN 2 THEN N''
                               
WHEN 3 THEN N''
                               
WHEN 4 THEN N''
                               
WHEN 5 THEN N''
                               
WHEN 6 THEN N'' END +N']'
   
FROM #weekday_table;
   
   
SET @columns=STUFF(@columns,1,1,'');
   
   
SET @sSQL=N'
        SELECT
'+@columns+N'
        FROM (
            SELECT
               DATEADD(day,number,@start_dt) AS dt,
               (DATEPART(weekday,DATEADD(day,number,@start_dt))+@@DATEFIRST-1)%7 AS [weekday],
               DATEPART(week,DATEADD(day,number,@start_dt)) AS [week]
            FROM master.dbo.spt_values AS A
                JOIN #weekday_table AS B
                    ON (DATEPART(weekday,DATEADD(day,number,@start_dt))+@@DATEFIRST-1)%7=B.[weekday]
            WHERE A.type=
''p''
            AND DATEADD(day,number,@start_dt)<=@end_dt
        ) AS A
        GROUP BY [week]
   
';
   
   
EXEC sp_executesql @sSQL,
             N
'@start_dt DATETIME,@end_dt DATETIME',
            
@start_dt,@end_dt;
            
GO

EXEC p '2009-04-01','2009-04-30','0,1,2,3,4,5,6'

GO
DROP PROC p

/*
周日                      周一                      周二                      周三                      周四                      周五                      周六
----------------------- ----------------------- ----------------------- ----------------------- ----------------------- ----------------------- -----------------------
NULL                    NULL                    NULL                    2009-04-01 00:00:00.000 2009-04-02 00:00:00.000 2009-04-03 00:00:00.000 2009-04-04 00:00:00.000
2009-04-05 00:00:00.000 2009-04-06 00:00:00.000 2009-04-07 00:00:00.000 2009-04-08 00:00:00.000 2009-04-09 00:00:00.000 2009-04-10 00:00:00.000 2009-04-11 00:00:00.000
2009-04-12 00:00:00.000 2009-04-13 00:00:00.000 2009-04-14 00:00:00.000 2009-04-15 00:00:00.000 2009-04-16 00:00:00.000 2009-04-17 00:00:00.000 2009-04-18 00:00:00.000
2009-04-19 00:00:00.000 2009-04-20 00:00:00.000 2009-04-21 00:00:00.000 2009-04-22 00:00:00.000 2009-04-23 00:00:00.000 2009-04-24 00:00:00.000 2009-04-25 00:00:00.000
2009-04-26 00:00:00.000 2009-04-27 00:00:00.000 2009-04-28 00:00:00.000 2009-04-29 00:00:00.000 2009-04-30 00:00:00.000 NULL                    NULL


(5 行受影响)
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值