在sql中创建具有非默认开始和结束年份日期的日历

时间:2011-08-23 08:48:23

标签: sql-server tsql

我需要创建在特定日期开始和结束的年历。它不是从1月1日开始,也不是在12月31日结束,而是在每年不同的日期(我以编程方式声明/设置它们)。这是学校(学年)的日历。目前明年将于10月1日开始,9月30日结束。我需要的是连续的周数,周开始和结束日期以及所有日期

因此,对于2011/2012学年的第一周(10月1日至9月30日),我会得到week number = 1week start date = 2011-10-01week end date = 2011-10-02(基本上每周有两行) )等等。

我遇到的问题是,在使用native Microsoft Date and Time functions时,我只能获得“默认年份范围”中的周数:

DATEPART(ww, [Date])

如果我在10月1日通过,鞋面将返回40.但我的结果应为1。

有任何建议如何做到这一点?我目前拥有的表格包括多年的所有日期(默认年份从1990年到2100年),默认周数和月份。我想从中选择日期范围(这将是我的学年开始和结束日期),并以某种方式分配正确的工作日期和开始和结束日期。

这不是一些学校项目或家庭作业对我的工作而言:)

2 个答案:

答案 0 :(得分:1)

在再次阅读你的问题后,我提出了这个问题

declare @start datetime
declare @end datetime

set @start = '2011-10-01'
set @end = '2012-9-30'

;with cte as
(
select @start firstday, @start + 6 - DATEDIFF(day, 0, @start) %7 lastday,  1 week
union all
select lastday + 1, case when @end < lastday + 7 then @end else lastday + 7 end,  week + 1
from cte
where lastday < @end
)
select cast(firstday as date) firstday, cast(lastday as date) lastday, week  from cte
option(MAXRECURSION 0) 

结果:

firstday   lastday    week
---------- ---------- ----
2011-10-01 2011-10-02 1
2011-10-03 2011-10-09 2
2011-10-10 2011-10-16 3
2011-10-17 2011-10-23 4
....
2012-09-17 2012-09-23 52
2012-09-24 2012-09-30 53

旧的消化

declare @start datetime
declare @end datetime

set @start = '2011-10-01'
set @end = '2012-9-30'

;with cte as
(
select @start calendardate, 1 week
union all
select calendardate + 1, week + case when DATEDIFF(day, 0, calendardate) %7 = 6 then 1 else 0 end
from cte
where calendardate < @end
)
select cast(calendardate as date) calendardate, week  from cte
option(MAXRECURSION 0) 

结果:

calendardate week
------------ -----------
2011-10-01   1
2011-10-02   1
2011-10-03   2
2011-10-04   2
2011-10-05   2
2011-10-06   2
2011-10-07   2
2011-10-08   2
2011-10-09   2
2011-10-10   3
2011-10-11   3
2011-10-12   3
.....
2012-09-29   53
2012-09-30   53

答案 1 :(得分:1)

[t-clausen.dk]的答案已经足够了,但你需要EndOfWeek和BeginOf Week:

DECLARE @start DATETIME
DECLARE @end DATETIME

SET @start = '2011-10-01'
SET @end = '2012-9-30';

WITH cte(calendardate, week, beginofweek, endofweek)
     AS (SELECT @start         calendardate,
                CAST(1 AS INT) week,
                Dateadd(DAY, 0, Datediff(DAY, 0, @start) -
                                Datediff(DAY, 0, @start) %
                                7)
                               beginofweek,
                Dateadd(DAY, 6, Datediff(DAY, 0, @start) -
                                Datediff(DAY, 0, @start) %
                                7)
         UNION ALL
         SELECT calendardate + 1,
                week + CASE
                         WHEN Datediff(DAY, 0, calendardate) %7 = 6 THEN 1
                         ELSE 0
                       END,
                Dateadd(DAY, 0, Datediff(DAY, 0, calendardate + 1) -
                                Datediff(DAY, 0, calendardate + 1) % 7)
                beginofweek,
                Dateadd(DAY, 6, Datediff(DAY, 0, calendardate) -
                                Datediff(DAY, 0, calendardate) % 7)
         FROM   cte
         WHERE  calendardate < @end)
SELECT CAST(calendardate AS DATE) calendardate,
       week,
       CAST(beginofweek AS DATE)  beginofweek,
       CAST(endofweek AS DATE)    endofweek
FROM   cte
OPTION( MAXRECURSION 0) 

结果:

calendardate week        beginofweek endofweek
------------ ----------- ----------- ----------
2011-10-01   1           2011-09-26  2011-10-02
2011-10-02   1           2011-09-26  2011-10-02
2011-10-03   2           2011-10-03  2011-10-02
2011-10-04   2           2011-10-03  2011-10-09
2011-10-05   2           2011-10-03  2011-10-09
2011-10-06   2           2011-10-03  2011-10-09
2011-10-07   2           2011-10-03  2011-10-09
2011-10-08   2           2011-10-03  2011-10-09
2011-10-09   2           2011-10-03  2011-10-09
2011-10-10   3           2011-10-10  2011-10-09
2011-10-11   3           2011-10-10  2011-10-16
2011-10-12   3           2011-10-10  2011-10-16
2011-10-13   3           2011-10-10  2011-10-16
2011-10-14   3           2011-10-10  2011-10-16
2011-10-15   3           2011-10-10  2011-10-16
2011-10-16   3           2011-10-10  2011-10-16
2011-10-17   4           2011-10-17  2011-10-16
2011-10-18   4           2011-10-17  2011-10-23

...

2012-09-21   52          2012-09-17  2012-09-23
2012-09-22   52          2012-09-17  2012-09-23
2012-09-23   52          2012-09-17  2012-09-23
2012-09-24   53          2012-09-24  2012-09-23
2012-09-25   53          2012-09-24  2012-09-30
2012-09-26   53          2012-09-24  2012-09-30
2012-09-27   53          2012-09-24  2012-09-30
2012-09-28   53          2012-09-24  2012-09-30
2012-09-29   53          2012-09-24  2012-09-30
2012-09-30   53          2012-09-24  2012-09-30