这是一种方法。我无法找到使用递归 CTE 的方法,因为您无法在递归 CTE 的递归部分中进行聚合。
DECLARE @MinDate DATE = '20170504',
@MaxDate DATE = '20170531'
DECLARE @StartDate datetime, @EndDate datetime
--DATE TABLE... ONE ROW FOR EVERY DAY IN RANGE
IF OBJECT_ID('tempdb..#DateTable') IS NOT NULL DROP TABLE #DateTable
SELECT TOP (DATEDIFF(DAY, @MinDate, @MaxDate) + 1)
Dates = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, @MinDate)
INTO #DateTable
FROM sys.all_objects a
CROSS JOIN sys.all_objects b
IF OBJECT_ID('tempdb..#Results') IS NOT NULL DROP TABLE #Results
CREATE TABLE #Results (Date1 DATETIME, Date2 DATETIME, NumOfDays INT)
--INSERT FIRST ROW IN CASE IT STARTS ON A DAY OTHER THAN SUNDAY
INSERT INTO #Results
SELECT
MIN(Dates) as Date1
,MIN(CASE WHEN DATEPART(WEEKDAY,Dates) = 7 THEN Dates END) as Date2
,DATEDIFF(DAY,MIN(Dates),MIN(CASE WHEN DATEPART(WEEKDAY,Dates) = 7 THEN Dates END)) + 1 as NoOfDays
FROM #DateTable
SET @StartDate = (SELECT MIN(CASE WHEN DATEPART(WEEKDAY,Dates) = 1 THEN Dates END) FROM #DateTable)
SET @EndDate = (SELECT MAX(CASE WHEN DATEPART(WEEKDAY,Dates) = 1 THEN Dates END) FROM #DateTable)
--INSERT ALL FULL WEEKS
WHILE @StartDate < @EndDate
BEGIN
INSERT INTO #Results
SELECT
MIN(Dates) as Date1
,MIN(CASE WHEN DATEPART(WEEKDAY,Dates) = 7 THEN Dates END) as Date2
,DATEDIFF(DAY,MIN(Dates),MIN(CASE WHEN DATEPART(WEEKDAY,Dates) = 7 THEN Dates END)) + 1 as NoOfDays
FROM #DateTable
WHERE Dates >= @StartDate
SET @StartDate = DATEADD(DAY,7,@StartDate)
END
--INSERT LAST ROW IF IT ISN'T A FULL WEEK
IF (SELECT MAX(Date2) FROM #Results) <> @MaxDate
BEGIN
INSERT INTO #Results
SELECT
MIN(Dates) as Date1
,MAX(Dates) as Date2
,DATEDIFF(DAY,MIN(Dates),MAX(Dates)) + 1 as NoOfDays
FROM #DateTable
WHERE Dates > (SELECT MAX(Date2) FROM #Results)
END
SELECT * FROM #Results
DROP TABLE #Results
DROP TABLE #DateTable
返回
+-------------------------+-------------------------+-----------+
| Date1 | Date2 | NumOfDays |
+-------------------------+-------------------------+-----------+
| 2017-05-04 00:00:00.000 | 2017-05-06 00:00:00.000 | 3 |
| 2017-05-07 00:00:00.000 | 2017-05-13 00:00:00.000 | 7 |
| 2017-05-14 00:00:00.000 | 2017-05-20 00:00:00.000 | 7 |
| 2017-05-21 00:00:00.000 | 2017-05-27 00:00:00.000 | 7 |
| 2017-05-28 00:00:00.000 | 2017-05-31 00:00:00.000 | 4 |
+-------------------------+-------------------------+-----------+