2017-10-11 108 views
4

我想根據他們本來可以完成的活動來計算客戶流失率,而不是按日期流失,這是正常情況。我們有與特定主機連接的事件,在我的示例中,所有事件都由Alice託管,但可能是不同的主機。填補空白,基於事件

所有遵循特定事件的人都應被放置在一個類別中(新的,活躍的,攪動的和復活的)。

:第一次一個人跟隨來自特定主機的事件。
活動:再次關注(並且還遵循了來自特定主持人的最後一個活動)。
攪動:追隨者有機會跟隨,但沒有。
復活:已經攪動的追隨者已經開始遵循先前遵循的主持人。

declare @events table (event varchar(50), host varchar(50), date date) 
declare @eventFollows table (event varchar(50), follower varchar(50)) 

insert into @events values ('e_1', 'Alice', GETDATE()) 
insert into @events values ('e_2', 'Alice', GETDATE()) 
insert into @events values ('e_3', 'Alice', GETDATE()) 
insert into @events values ('e_4', 'Alice', GETDATE()) 
insert into @events values ('e_5', 'Alice', GETDATE()) 

insert into @eventFollows values ('e_1', 'Bob') --new 
insert into @eventFollows values ('e_2', 'Bob') --active 
--Bob churned 
insert into @eventFollows values ('e_4', 'Megan') --new 
insert into @eventFollows values ('e_5', 'Bob') --resurrected 
insert into @eventFollows values ('e_5', 'Megan') --active 

select * from @events 
select * from @eventFollows 

預期的結果應該是這樣的

select 'e_1', 1 as New, 0 as resurrected, 0 as active, 0 as churned --First time Bob follows Alice event 
union all 
select 'e_2', 0 as New, 0 as resurrected, 1 as active, 0 as churned --Bob follows the next event that Alice host (considered as Active) 
union all 
select 'e_3', 0 as New, 0 as resurrected, 0 as active, 1 as churned --Bob churns since he does not follow the next event 
union all 
select 'e_4', 1 as New, 0 as resurrected, 0 as active, 0 as churned --First time Megan follows Alice event 
union all 
select 'e_5', 0 as New, 1 as resurrected, 1 as active, 0 as churned --Second time (active) for Megan and Bob is resurrected 

我開始用類似下面的查詢,但問題是,我不明白的是,追隨者也沒有的所有事件跟隨(但可能已經跟隨)。

select a.event, follower, date, 
    LAG (a.event,1) over (partition by a.host, ma.follower order by date) as lag, 
    LEAD (a.event,1) over (partition by a.host, ma.follower order by date) as lead, 
    LAG (a.event,1) over (partition by a.host order by date) as lagP, 
    LEAD (a.event,1) over (partition by a.host order by date) as leadP 
from @events a left join @eventFollows ma on ma.event = a.event order by host, follower, date 

任何想法?

+0

「攪動」後會發生什麼?他們攪拌一次還是停止攪動? – gbn

+0

每個人或COUNT個人的標誌是? – gbn

+0

當你流失後,你可以重新復活,然後你可以再次攪動。在我的例子中,鮑勃攪動(即將離開事件3和事件4),但在事件5復活。 – corpat

回答

1

這看起來可能有點間接的方式,但它可以通過在號碼間隙檢查,以檢測島嶼:

;with nrsE as 
(
    select *, ROW_NUMBER() over (order by event) rnrE from @events 
), nrs as 
(
    select f.*,host, rnrE, ROW_NUMBER() over (partition by f.follower, e.host order by f.event) rnrF 
    from nrsE e 
    join @eventFollows f on f.event = e.event 
), f as 
(
    select host, follower, min(rnrE) FirstE, max(rnrE) LastE, ROW_NUMBER() over (partition by follower, host order by rnrE - rnrF) SeqNr 
    from nrs 
    group by host, follower, rnrE - rnrF --difference between rnr-Event and rnr-Follower to detect gaps 
), stat as --from the result above on there are several options. this example uses getting a 'status' and pivoting on it 
(
    select e.event, e.host, case when f.FirstE is null then 'No participants' when f.LastE = e.rnrE - 1 then 'Churned' when rnrE = f.FirstE then case when SeqNr = 1 then 'New' else 'Resurrected' end else 'Active' end Status 
    from nrsE e 
    left join f on e.rnrE between f.FirstE and f.LastE + 1 and e.host = f.host 
) 
select p.* from stat pivot(count(Status) for Status in ([New], [Resurrected], [Active], [Churned])) p 

最後2可以簡化步驟,但通過這種方式獲取'狀態'可能可以在其他情況下重複使用

0

這符合你的期望的結果

SELECT 
    X.event, X.host, X.date, 
    IsNew = SUM(CASE WHEN X.FirstFollowerEvent = X.event THEN 1 ELSE 0 END), 
    IsActive = SUM(CASE WHEN X.lagFollowerEvent = X.lagEvent THEN 1 ELSE 0 END), 
    IsChurned = SUM(CASE WHEN X.follower IS NULL THEN 1 ELSE 0 END), 
    IsResurrected = SUM(CASE WHEN X.lagFollowerEvent <> X.lagEvent AND X.FirstFollowerEvent IS NOT NULL THEN 1 ELSE 0 END) 
FROM 
    (
    select 
     a.event, a.host, ma.follower, a.date, 
     FIRST_VALUE(a.event) over (partition by a.host, ma.follower order by a.date, a.event) as FirstFollowerEvent, 
     LAG (a.event,1) over (partition by a.host, ma.follower order by a.date, a.event) as lagFollowerEvent, 
     LAG (a.event,1) over (partition by a.host order by a.date, a.event) as lagEvent 
    FROM 
     @events a 
     LEFT join 
     @eventFollows ma on a.event = ma.event 
    ) X 
GROUP BY 
    X.event, X.host, X.date 
ORDER by 
    X.event, X.host, X.date 
+0

謝謝!但是,有一些問題。首先,我需要改變是否新款到'是否新款= SUM(CASE WHEN X.FirstFollowerEvent = X.event和X.follower IS NOT NULL THEN 1 ELSE 0 END),' 而且,如果我再補充一點庫珀遵循E_2我預計他在e_3中流失,但e_3中的計數僅爲1. 'insert into @eventFollows values('e_2','Cooper')' 類似的問題是,如果我將某人添加到我期望的e_1在e_2中流失,e_2的流失列仍然爲零。例如。 'insert into @eventFollows values('e_1','Donald')' – corpat

+0

@corpat:我即將更新答案 – gbn