2

如何编写一个查询来返回两个日期之间工作日周的开始和结束日期?

例子:

declare 
  @startDate date = '2013-07-01'
  , @endDate date = '2013-09-30'

SELECT WeekData(@startDate, @endDate)

结果:

Name, Week1Start, Week1End, Week2Start, Week2End, Week3Start, Week3End, Week4Start, Week4End, Week5Start, Week5End
---------------------------------------------------------------------------------------------------------------------------------------------------
'July 2013', '2013-07-01', '2013-07-05', '2013-07-08', '2013-07-12', '2013-07-15', '2013-07-19', '2013-07-22', '2013-07-26', '2013-07-29', '2013-07-31'
'August 2013', '2013-08-01', '2013-08-02', '2013-08-05', '2013-08-09', '2013-08-12', '2013-08-16', '2013-08-19', '2013-08-23', '2013-08-26', '2013-08-30'
'September 2013', '2013-09-02', '2013-09-06', '2013-09-09', '2013-09-13', '2013-09-16', '2013-09-20', '2013-09-23', '2013-08-27', '2013-09-30', '2013-09-30'

工作周从星期一或每月的第一天开始,到星期五或每月的最后一天结束。

4

2 回答 2

2

输出是否必须采用您给定的确切格式?如果您想要给定范围内匹配日期的完整列表,我会想到的方法是使用某种 T-SQL 循环,引用 DATEPART(或 DATENAME,如上一个答案)。

DECLARE @startDate DATETIME = '7/1/2013', @endDate DATETIME = '9/30/2013';

DECLARE @currentDate DATETIME = @startDate;
DECLARE @currentMonth INT, @currentDay INT, @currentDayOfWeek INT;
DECLARE @prevMonth INT = 0, @prevDay INT = 0;

WHILE @currentDate <= @endDate
BEGIN 
    SET @currentMonth = MONTH(@currentDate);
    SET @currentDay = DAY(@currentDate);

    -- see if we need a month header
    IF(@currentMonth <> @prevMonth) 
    BEGIN 
        PRINT 'Month: ' + CAST(@currentMonth AS VARCHAR) + '/' + CAST(YEAR(@currentDate) AS VARCHAR);
        SET @prevMonth = @currentMonth;
    END

    -- see if it is a week start or end
    SET @currentDayOfWeek = DATEPART(WEEKDAY, @currentDate);
    IF( (@currentDay = 1)
        OR (@currentDay = 31) -- this would obviously need to be more sophisticated
        OR (@currentDayOfWeek = 2) -- Monday
        OR (@currentDayOfWeek = 6) -- Friday
    ) PRINT @currentDate;

    -- go on to the next date
    SET @currentDate = @currentDate + 1;
END
于 2013-09-27T23:05:23.100 回答
0

我想我参加聚会有点晚了,但我刚刚和这个摔跤了。这是我过去两年工作周生成的内容(假设周日是一周的开始,周六是结束):

Declare @workWeeks Table (
    weekStart datetime,
    weekEnd datetime,
    weekText varchar(25)
)

Declare @count int,
        @lastSunday datetime,
        @nextSaturday datetime
Select  @count = 0,
        @lastSunday = DATEADD(DAY, DATEDIFF(DAY, -1, GETDATE()) / 7 * 7, -1),
        @nextSaturday = DATEADD(MS, -3, DATEADD(DAY, DATEDIFF(DAY, -1, GETDATE()) / 7 * 7, 6)) -- Next Sunday minus 3 ms

While @count < 52
Begin
    Insert Into @workWeeks Values(
        DATEADD(WK, -@count, @lastSunday),
        DATEADD(WK, -@count, @nextSaturday),
        CONVERT(varchar, DATEADD(WK, -@count, @lastSunday), 101) + ' - ' + CONVERT(varchar, DATEADD(WK, -@count, @nextSaturday), 101))
    Set @count = @count + 1
End

Select * From @workWeeks

你会得到这个:

weekStart               weekEnd                 weekText
----------------------- ----------------------- -------------------------
2015-06-14 00:00:00.000 2015-06-20 23:59:59.997 06/14/2015 - 06/20/2015
2015-06-07 00:00:00.000 2015-06-13 23:59:59.997 06/07/2015 - 06/13/2015
2015-05-31 00:00:00.000 2015-06-06 23:59:59.997 05/31/2015 - 06/06/2015
2015-05-24 00:00:00.000 2015-05-30 23:59:59.997 05/24/2015 - 05/30/2015
...

您可以通过在用于设置@lastSunday 和@nextSaturday 的表达式末尾的日期调整值进行猴子调整,在此示例中分别为-1 和6,来更改考虑一周的开始和结束日期的内容。

但是,如果我正确地阅读了您的原始问题,您只需要本周的周一至周五,对吗?在这种情况下,只需在插入语句中的每个方向调整一天,如下所示:

-- For Mon thru Fri:
Insert Into @workWeeks Values(
    DATEADD(WK, -@count, DATEADD(DD, 1, @lastSunday)),
    DATEADD(WK, -@count, DATEADD(DD, -1, @nextSaturday)),
    CONVERT(varchar, DATEADD(WK, -@count, DATEADD(DD, 1, @lastSunday)), 101) + ' - ' + CONVERT(varchar, DATEADD(WK, -@count, DATEADD(DD, -1, @nextSaturday)), 101))

你会得到这个:

weekStart               weekEnd                 weekText
----------------------- ----------------------- -------------------------
2015-06-15 00:00:00.000 2015-06-19 23:59:59.997 06/15/2015 - 06/19/2015
2015-06-08 00:00:00.000 2015-06-12 23:59:59.997 06/08/2015 - 06/12/2015
2015-06-01 00:00:00.000 2015-06-05 23:59:59.997 06/01/2015 - 06/05/2015
2015-05-25 00:00:00.000 2015-05-29 23:59:59.997 05/25/2015 - 05/29/2015
...
于 2015-06-16T18:38:29.327 回答