计算每月的新响应和累积百分比

时间:2013-12-16 10:09:24

标签: sql-server sql-server-2008

如果我有几个客户月复一月地回复,我想只计算他们回复的第一个月。我可以通过为每个月创建临时表并比较月份来实现这一点,但是它看起来很丑,有几个临时表。我很确定有更好的方法(我不知道Rank()是否有效)。有人可以给我看代码吗?


    declare @Something table
(
    CustID Char(10),
    MthId char(2),
    ResponseDate datetime
)

insert @Something select 'Cust1', '1', '5/6/13' union all select 'Cust1', '2', '6/13/13' union all select 'Cust1', '3', '7/13/13' union all select 'Cust2', '1', '5/20/13' union all select 'Cust2', '2', '6/22/13' union all select 'Cust3', '2', '6/20/13' union all select 'Cust4', '2', '6/24/13' union all select 'Cust4', '3', '7/24/13' union all select 'Cust5', '4', '8/28/13' union all select 'Cust6', '3', '7/24/13'

这是我期待的3列输出(我真的不需要第2列 - 它可以在那里进一步解释)

月份,当月有多少“累计”新客户回复,每月联系新客户的累计百分比是多少。

MthId   NewCustomerResponse CumulativeNewCustomerResponse Cumulative%Responded    
1       2                     2                            33.3     
2       2                     4                            66.7     
3       1                     5                            83.3 
4       1                     6                            100.0    

2 个答案:

答案 0 :(得分:2)

包括您的新专栏:

SQLFiddle解决方案

;with cte as(
select 
ROW_NUMBER() over (partition by CustID order by responseDate) as seq
,* from @Something
)
,cte2 as( 
select 
 MthId
,(select Count(*) from cte t2 where t1.MthId=t2.MthId and t2.seq=1) NewCustomerResponse
,(select COUNT(*) from cte t2 where t1.MthId>=t2.MthId and t2.seq=1)     CumulativeNewCustomerResponse
,(select COUNT(CustID) from cte where seq=1) total
from cte t1
group by MthId
)

select 
MthID
,NewCustomerResponse
,CumulativeNewCustomerResponse
,(cast(CumulativeNewCustomerResponse as decimal(3,1))/CAST(total as decimal(3,1)))*100
from cte2 t1

答案 1 :(得分:1)

检查一下,

 declare @Something table
    (
        CustID Char(10),
        MthId char(2),
        ResponseDate datetime
    )
    insert into @Something
     select 'Cust1', '1', '5/6/13' 
     union all 
     select 'Cust1', '2', '6/13/13' 
     union all 
     select 'Cust1', '3', '7/13/13' 
     union all 
     select 'Cust2', '1', '5/20/13' 
     union all 
     select 'Cust2', '2', '6/22/13' 
     union all
     select 'Cust3', '2', '6/20/13' union all
    select 'Cust4', '2', '6/24/13' union all
    select 'Cust4', '3', '7/24/13' union all
    select 'Cust5', '4', '8/28/13' union all
    select 'Cust6', '3', '7/24/13'

    ;with CTE as
    (select *,dense_rank()over(partition by custid order by mthid)rn from @Something)
    ,CTE1 as
    (select a.MthId,count(*) NewCustomerResponse  from cte a where rn=1 group by a.MthId )
    ,cte2 as
    (select sum(NewCustomerResponse) totalresponse from cte1)
,cte4 as
(
select  a.MthId
,(Select sum(NewCustomerResponse)  from CTE1 c where c.mthid<=a.mthid) CumulativeNewCustomerResponse

from cte1 a cross apply cte2 b
)





   select  a.MthId,a.NewCustomerResponse
,(Select sum(NewCustomerResponse)from CTE1 c where c.mthid<=a.mthid)CumulativeNewCustomerResponse 
,case when b.totalresponse>0 then cast((d.CumulativeNewCustomerResponse /cast(b.totalresponse as float))*100 as decimal(10,2)) else 0 end [Cumulative%Responded] 
from cte1 a 
inner join cte4 d on a.MthId=d.MthId
cross apply cte2 b