我正在努力想出一个可以在初始事件发生后的30天内给出重复百分比的查询,但只计算30天内任何事件作为单个重复。这是一个人的样本数据集:
人日期
══════════════
A 3/1/14
A 3/21/14
A 3/29/14
A 4/14/14
2014年4月17日
在这种情况下,3/21将是重复事件,而3/29不会被计为秒。 4/14将是下一个窗口的开始,4/17是第二个重复。
要计算此处重复的百分比,分子将是在该月内具有初始事件且在30天内发生后续事件的人的独特计数。分母是当月发生事件的人数。在跨越月份的情况下,重复计算在初始事件的月份内。
我知道我可以想出一些使用循环/光标或临时表的东西,但随着数据集的增长,它将需要永远。有没有人对如何将此作为单个查询有任何想法?它可能涉及几个CTE。到目前为止我提出的所有事情都失败了。
答案 0 :(得分:1)
很好...试试这个:
create table #t (Person varchar(10), EventDate date);
insert #t (Person, EventDate)
values
('A', '3/1/14'),
('A', '3/21/14'),
('A', '3/29/14'),
('A', '4/14/14'),
('A', '4/17/14'),
('A', '8/3/14'),
('B', '3/25/14'),
('B', '4/2/14'),
('B', '4/20/14'),
('B', '6/14/14'),
('B', '8/17/14'),
('B', '8/26/14');
;WITH OrderedEvents AS (
SELECT Person, EventDate, ROW_NUMBER() OVER (PARTITION BY Person ORDER BY EventDate) AS Ord
FROM #t
)
, RepeatedEvents AS (
SELECT Person, EventDate, Ord, EventDate AS InitialDate
FROM OrderedEvents
WHERE Ord = 1
UNION ALL
SELECT o.Person, o.EventDate, o.Ord
, CASE WHEN DATEDIFF(DAY, r.InitialDate, o.EventDate) > 30 THEN o.EventDate ELSE r.InitialDate END
FROM OrderedEvents o
JOIN RepeatedEvents r ON o.Person = r.Person AND o.Ord = r.Ord + 1
)
, GroupedEvents AS (
SELECT Person, MONTH(InitialDate) AS Mth, YEAR(InitialDate) AS Yr
, IsRepeat = CASE WHEN COUNT(*) > 1 THEN 1 ELSE 0 END
FROM RepeatedEvents
GROUP BY Person, MONTH(InitialDate), YEAR(InitialDate)
)
SELECT Mth, Yr, CAST(SUM(IsRepeat) AS NUMERIC) / CAST(COUNT(DISTINCT person) AS NUMERIC) AS Pct
FROM GroupedEvents
GROUP BY Mth, Yr;