Я знаю, что вы просили рекурсивный CTE, но без новых улучшений управления окнами в SQL Server 2012 (FIRST_VALUE () и т. Д.) Я думаю, что писать так будет непросто, когда вы должны отслеживать не только предыдущая строка, но также и более ранние строки одновременно. Вот версия курсора, которая, я считаю, достигает того, что вы хотите:
DECLARE @f TABLE([Key] INT, ID INT, VISITDATE DATE);
INSERT @f VALUES
(1 ,1,'2011-01-07'), (2 ,1,'2011-01-09'), (3 ,2,'2011-01-10'), (4 ,1,'2011-01-12'),
(5 ,3,'2011-01-12'), (6 ,1,'2011-01-18'), (7 ,2,'2011-01-21'), (9 ,1,'2011-02-28'),
(10,2,'2011-03-21'), (11,1,'2011-01-06'), (12,1,'2011-03-01');
DECLARE @ID INT, @dt DATE;
DECLARE @result TABLE(ID INT, FirstDate DATE, VisitCount INT);
DECLARE c CURSOR LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR SELECT ID, VISITDATE FROM @f ORDER BY ID, VISITDATE;
OPEN c;
FETCH NEXT FROM c INTO @ID, @dt;
WHILE @@FETCH_STATUS = 0
BEGIN
IF NOT EXISTS
(
SELECT 1 FROM @result WHERE ID = @ID
AND DATEDIFF(DAY, FirstDate, @dt) <= 10 -- maybe < 10?
)
INSERT @result SELECT @ID, @dt, 1;
FETCH NEXT FROM c INTO @ID, @dt;
END
SELECT ID, FirstDate FROM @result;
SELECT ID, VisitCount = COUNT(*) FROM @result GROUP BY ID;
CLOSE c;
DEALLOCATE c;
Результаты:
ID FirstDate
----------- ----------
1 2011-01-06
1 2011-01-18
1 2011-02-28
2 2011-01-10
2 2011-01-21
2 2011-03-21
3 2011-01-12
ID VisitCount
----------- -----------
1 3
2 3
3 1
Да, я знаю, что вас всегда предупреждают не разговаривать с незнакомцами и держаться подальше от курсоров, но в некоторых случаях они являются наиболее простым решением (и иногда могут выполнять лучше, чем многократные сканирования, чем решение на основе набора). может понести).