:
CREATE TABLE MyTable (ID INT, Date DATETIME, Allocation INT);
INSERT INTO MyTable VALUES (1, {d '2012-01-01'}, 0);
INSERT INTO MyTable VALUES (2, {d '2012-01-02'}, 2);
INSERT INTO MyTable VALUES (3, {d '2012-01-03'}, 0);
INSERT INTO MyTable VALUES (4, {d '2012-01-04'}, 0);
INSERT INTO MyTable VALUES (5, {d '2012-01-05'}, 0);
INSERT INTO MyTable VALUES (6, {d '2012-01-06'}, 5);
GO
この試し:クエリの最初のセクションが割り当て= 0であるすべての行によって固定されている再帰SELECT、ある
WITH DateGroups (ID, Date, Allocation, SeedID) AS (
SELECT MyTable.ID, MyTable.Date, MyTable.Allocation, MyTable.ID
FROM MyTable
LEFT JOIN MyTable Prev ON Prev.Date = DATEADD(d, -1, MyTable.Date)
AND Prev.Allocation = 0
WHERE Prev.ID IS NULL
AND MyTable.Allocation = 0
UNION ALL
SELECT MyTable.ID, MyTable.Date, MyTable.Allocation, DateGroups.SeedID
FROM MyTable
JOIN DateGroups ON MyTable.Date = DATEADD(d, 1, DateGroups.Date)
WHERE MyTable.Allocation = 0
), StartDates (ID, StartDate, DayCount) AS (
SELECT SeedID, MIN(Date), COUNT(ID)
FROM DateGroups
GROUP BY SeedID
), EndDates (ID, EndDate) AS (
SELECT SeedID, MAX(Date)
FROM DateGroups
GROUP BY SeedID
)
SELECT StartDates.StartDate, EndDates.EndDate, StartDates.DayCount
FROM StartDates
JOIN EndDates ON StartDates.ID = EndDates.ID;
、およびその前日は存在しないか、または割り当て!= 0になります。これは、戻りたい期間の開始日であるID:1と3を効果的に返します。
この同じクエリの再帰部分は、アンカー行から開始し、allocation = 0も持つすべての後続の日付を検出します。SeedIDは、すべての反復を通じて固定IDを追跡します。次のサブクエリは、各SeedIDのためのすべての開始日をフィルタリングするために、単純なGROUP BYを使用し、また、日カウント
ID Date Allocation SeedID
----------- ----------------------- ----------- -----------
1 2012-01-01 00:00:00.000 0 1
3 2012-01-03 00:00:00.000 0 3
4 2012-01-04 00:00:00.000 0 3
5 2012-01-05 00:00:00.000 0 3
:
結果は、これまでのところ、このです。
最後のサブクエリは終了日で同じことを行いますが、今回はすでにこのように日数が必要ではありません。
最後のSELECTクエリは、これらの2つを結合して開始日と終了日を結合し、それらを日数とともに返します。
@ istariは終了日です。テーブル構造の列 – Devjosh
カーソルを使用しようとしましたか?カーソルが不要です – Vikram
「1日離れている」のように「連続」を意味しますか、「行が日付順にソートされているときに隣接していますか?つまり、すべての固有の日付は '日付'の列に一度だけ表示されますか? – gcbenison