数百万行のデータベースからデータを取得するスクリプトに取り組んでおり、期間のギャップに問題があります。10 日未満のギャップはまったくギャップと見なすべきではないと判断しました。したがって、これらのギャップは削除する必要があります (以下の例を参照してください。太字の日付は、「実際の」関心期間を形成します)。
- ID InDate OutDate
- 1 2008-10-10 2009-02-05
- 1 2009-02-08 2009-05-13
- 1 2011-01-01 2011-05-20
- 2 2007-03-17 2008-10-19
- 2 2009-05-30 2010-10-12
- 2 2010 年 10 月 14 日 2010 年 12 月 31日
したがって、いくつかの問題が発生します。最初の問題は、単一の期間に変換される期間について、どの Outdate と Indate が互いに近いかを特定することです。次の問題は、Outdate を上位の行番号から下位の行番号 (つまり、テーブルの上) に移動することです。最後の問題は、現在重複している行を特定して取り除くことです。
以下の質問を解決しようとしました。最初の 2 つの問題は、表 #t4a で解決されています。テーブル #t4aa の戦略は、問題の重複行を新しい (ダミー) 変数でマークすることによって重複を取り除き、後の段階でそのような値 (1:s) をすべて取り除くことです。しかし、うまくいきません!すべての行は、1 でマークされるべきものであっても、0 でマークされます。何か提案はありますか?
-- この一時テーブルはギャップを測定し、新しい変数 OutDate2 を作成します。この変数は、小さなギャップ (11 日未満) の場合、元の値の代わりに次の Outdate を行に書き込みます。
WITH C AS (SELECT Id, InDate, OutDate, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY InDate) Rownum FROM #t4 t4)
SELECT cur.Rownum, cur.Id, cur.InDate CurInDate, cur.OutDate, nxt.InDate NxtInDate, DATEDIFF(day, cur.OutDate, nxt.InDate) Number_of_days,
CASE WHEN DATEDIFF(day, cur.OutDate, nxt.InDate)<11 AND DATEDIFF(day, cur.OutDate, nxt.InDate)>0 THEN nxt.OutDate ELSE cur.OutDate END AS OutDate2
INTO #t4a
FROM C cur
LEFT OUTER JOIN C nxt ON (nxt.rownum=cur.rownum+1 AND nxt.Id=cur.Id)
-- この一時テーブルは、行の OVERLAP を識別するダミーを作成し、後の一時テーブルでこれらを削除できるようにします。動かないのはこのテーブルです。
WITH C AS (SELECT Id, InDate, OutDate, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY InDate) rownum FROM #t4a)
SELECT cur.Id, cur.InDate, nxt.OutDate2,
CASE WHEN cur.OutDate2 < nxt.InDate THEN 1.0 ELSE 0.0
END AS Overlap
INTO #t4aa
FROM C cur
LEFT OUTER JOIN C nxt on (cur.rownum=nxt.rownum+1 AND cur.Id=nxt.Id)