2011-03-10 84 views
2

我試圖將連續日期範圍分組以顯示每個範圍的最小和最大日期。到目前爲止,我已經使用了一個類似於這個的解決方案:http://www.sqlservercentral.com/articles/T-SQL/71550/但是我在SQL 2000上,所以我不得不做一些改變。這是我的程序到目前爲止:按連續日期分組,忽略SQL中的週末

create table #tmp 
(
date smalldatetime, 
rownum int identity 
) 

insert into #tmp 
select distinct date from testDates order by date 

select 
min(date) as dateRangeStart, 
max(date) as dateRangeEnd, 
count(*) as dates, 
dateadd(dd,-1*rownum, date) as GroupID 
from #tmp 
group by dateadd(dd,-1*rownum, date) 

drop table #tmp 

它的工作原理是我想要的除了一個問題:週末。我的數據集沒有周末日期的記錄,這意味着找到的任何組最多隻有5天。例如,在下面的結果,我想最後3組顯示爲一個單一的記錄,用10/6一dateRangeStart和10/20一dateRangeEnd:

screenshot of results

有一些我可以設置這種方式來忽略日期範圍內的休息,如果這個休息只是一個週末?

感謝您的幫助。

+0

爲什麼不創建一個永久的帶有星期編號列的日曆表? –

+0

@Martin你能詳細解釋一下嗎?我總是可以使用datepart獲得星期編號,但我不明白這將如何幫助改變我的分組。 – Colin

+0

哦,對了,我讀錯了問題。 –

回答

2

EDITED

我不喜歡我以前的想法非常多。我認爲這是一個更好的方法:

  1. 根據要分組的那組中的第一個和最後一個日期,準備所有中間週末日期的列表。
  2. 將工作日期與週末日期一起插入,因此它們將根據其正常順序分配rownum值。
  3. 使用您發現連續範圍進行了以下修改方法:

    1)計算dateRangeStart時,如果它是一個週末的時間,挑最近的下一工作日; 2)因此對於dateRangeEnd,如果是週末日期,則選擇最近的前一個工作日; 3)當計算該組的日期時,只選擇工作日。

  4. 從結果集合中只選擇dates > 0的那些行,從而消除僅在週末形成的組。

而這裏的方法,其中假設的實現,一個星期上週日開始(DATEPART回報1)和週末日是星期天和星期六:

DECLARE @tmp TABLE (date smalldatetime, rownum int IDENTITY); 
DECLARE @weekends TABLE (date smalldatetime); 
DECLARE @minDate smalldatetime, @maxDate smalldatetime, @date smalldatetime; 
/* #1 */ 
SELECT @minDate = MIN(date), @maxDate = MAX(date) 
FROM testDates; 
SET @date = @minDate - DATEPART(dw, @minDate) + 7; 
WHILE @date < @maxDate BEGIN 
    INSERT INTO @weekends 
    SELECT @date UNION ALL 
    SELECT @date + 1; 
    SET @date = @date + 7; 
END; 
/* #2 */ 
INSERT INTO @tmp 
SELECT date FROM testDates 
UNION 
SELECT date FROM @weekends 
ORDER BY date; 
/* #3 & #4 */ 
SELECT * 
FROM (
    SELECT 
    MIN(date + CASE DATEPART(dw, date) WHEN 1 THEN 1 WHEN 7 THEN 2 ELSE 0 END) 
     AS dateRangeStart, 
    MAX(date - CASE DATEPART(dw, date) WHEN 1 THEN 2 WHEN 7 THEN 1 ELSE 0 END) 
     AS dateRangeEnd, 
    COUNT(CASE WHEN DATEPART(dw, date) NOT IN (1, 7) THEN date END) AS dates, 
    DATEADD(d, -rownum, date) AS GroupID 
    FROM @tmp 
    GROUP BY DATEADD(d, -rownum, date) 
) s 
WHERE dates > 0; 
+0

謝謝!這很好。我曾想過插入週末日期來解決範圍問題,但我認爲這會比這更困難。 – Colin