2011-03-10 16 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 

私は1つの問題を除いて私が望むとおりに動作します:週末。データセットには週末の日付は記録されていないため、見つかったグループは最大5日間です。例えば、以下の結果では、私は10/6のdateRangeStartと10/20のdateRangeEndで、単一のレコードとして表示するために、最後の3つのグループをしたいと思います:

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

関連する問題