2

連続する日付範囲をグループ化して、各範囲の最小日付と最大日付を表示しようとしています。これまでのところ、次のようなソリューションを使用してきました: http://www.sqlservercentral.com/articles/T-SQL/71550/ただし、SQL 2000 を使用しているため、いくつかの変更を加える必要がありました。これまでの私の手順は次のとおりです。

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 日です。たとえば、以下の結果では、最後の 3 つのグループが 10/6 の dateRangeStart と 10/20 の dateRangeEnd を持つ単一のレコードとして表示されるようにします。

結果のスクリーンショット

休憩が週末だけの場合、日付範囲の休憩を無視するように設定する方法はありますか?

助けてくれてありがとう。

4

1 に答える 1

2

編集済み

私は以前の考えがあまり好きではありませんでした。これはより良いものだと思います:

  1. グループ化する一連の最初の日付と最後の日付に基づいて、すべての中間の週末の日付のリストを準備します。
  2. 勤務日と週末の日付を並べて挿入rownumし、通常の順序に従ってすべての値が割り当てられるようにします。
  3. 次の変更を加えて、連続した範囲を見つける方法を使用します。

    1) を計算するときdateRangeStart、それが週末の日付の場合は、最も近い次の平日を選択します。

    2) それに応じてdateRangeEnd、週末の日付の場合は、最も近い前の平日を選択します。

    3) グループの日付をカウントするときは、平日のみを選択します。

  4. 結果のセットから の行のみを選択しdates > 0、週末だけで形成されたグループを除外します。

そして、これはメソッドの実装です。ここでは、週は日曜日に始まり ( DATEPARTreturn 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;
于 2011-03-11T07:23:54.420 に答える