TSQL - SQL 2008 - 在一个日期范围(开始日期到结束日期)之间是否可以通过(并排除)周末将此范围分成单独的行?

时间:2015-05-13 14:26:54

标签: sql-server sql-server-2008 tsql date weekend

我为措辞不佳的头衔道歉,我被赋予了超出我有限技能的任务,并希望有人可以提供帮助。

我们的员工有24/7的日程安排预约工作和现场分配(周末也是如此),但这不适用于度假。因此,我的任务是在周末打破一个日期范围(并排除它们)

例如:

开始日期: 2015年4月30日结束日期: 13/05/2015

30/04/2015, 01/05/2015
04/05/2015, 05/05/2015, 06/05/2015, 07/05/2015, 08/05/2015,
11/05/2015, 12/05/2015, 13/05/2015,

注意:周末已被排除在外,并且三个星期内日期范围已分为三个。

最好:包括每个范围的起点和终点

30/04/2015 - 01/05/2015 --(the same as it is the start and end dates)
04/05/2015 - 08/05/2015
11/05/2015 - 13/05/2015

我不知道这是否可能,因为我的知识非常有限,希望我已经解释得足以让某种灵魂可以看到这样的事情是否可能。

我们使用的数据库应用程序是SQL 2008上的TSQL。

非常感谢。

2 个答案:

答案 0 :(得分:0)

感谢有趣的问题。注意:我使用标准日期格式,但概念是相同的。

DECLARE @StartDate  DATE = '20150430',  --April 30, 2015
        @EndDate    DATE = '20150513';  --May 13,2015

WITH CTE_Dates
AS
(
    SELECT @StartDate dates
    UNION ALL
    SELECT DATEADD(DAY,1,dates)
    FROM CTE_Dates
    WHERE dates < @EndDate
),
CTE_weeks
AS
(
    SELECT  dates,
            DATEPART(WEEK,dates) WeekID
    FROM CTE_Dates
    WHERE DATENAME(WEEKDAY,dates) NOT IN ('Saturday','Sunday') --doesn't include weekends
)

SELECT  WeekID,
        MIN(dates) StartDate,
        MAX(dates) EndDate,
        STUFF(list_dates,1,1,'') list
FROM CTE_weeks A
CROSS APPLY (
                SELECT ',' + CAST(dates AS VARCHAR(100))
                FROM CTE_weeks B
                WHERE A.WeekID = B.WeekID
                ORDER BY dates
                FOR XML PATH('')
            ) CA(list_dates)
GROUP BY WeekID,STUFF(list_dates,1,1,'')

结果:

WeekID      StartDate  EndDate    list
----------- ---------- ---------- ------------------------------------------------------------
18          2015-04-30 2015-05-01 2015-04-30,2015-05-01
19          2015-05-04 2015-05-08 2015-05-04,2015-05-05,2015-05-06,2015-05-07,2015-05-08
20          2015-05-11 2015-05-13 2015-05-11,2015-05-12,2015-05-13

答案 1 :(得分:-1)

这似乎有效。它假定你给它一个工作日的开始日期:

declare @StartDate datetime = '20150430'
declare @EndDate datetime = '20150513'

; With Ord as (
    select @StartDate as StartAt,@StartDate as EndAt
    union all
    select StartAt,DATEADD(day,1,EndAt)
    from Ord where DATEPART(weekday,EndAt) != DATEPART(weekday,'20150710') --Known Friday
    and EndAt < @EndDate
    union all
    select DATEADD(day,3,EndAt),DATEADD(day,3,EndAt)
    from Ord where DATEPART(weekday,EndAt) = DATEPART(weekday,'20150710') --Still known Friday
    and DATEADD(day,3,EndAt) <= @EndDate
)
select StartAt,MAX(EndAt) as EndAt
from Ord
group by StartAt

结果:

StartAt                 EndAt
----------------------- -----------------------
2015-04-30 00:00:00.000 2015-05-01 00:00:00.000
2015-05-04 00:00:00.000 2015-05-08 00:00:00.000
2015-05-11 00:00:00.000 2015-05-13 00:00:00.000

我使用&#34;已知商品&#34;进行DATEPART的比较。 (即我只是从日历中随机选择一个)星期五,以便此代码适用于任何DATEFIRST设置。