如何计算SQL中的损耗率

时间:2015-10-13 17:21:06

标签: sql sql-server loops

表结构是

userID - 唯一ID

结算月 - 支付账单的月份

我拥有的数据为1年或12个月

我必须计算每个月离开的用户总数。

提前致谢。

4 个答案:

答案 0 :(得分:1)

如果您考虑在SQL Server中使用WHILE循环,那么90%的时间都是错误的。使用基于集合的方法!

在您的情况下,您可以将表格加入到自己可以计算下个月缺少的客户数量:

SELECT      t1.BillingMonth,
            Attrition = COUNT(*)
FROM        #my_table   t1
LEFT JOIN   #my_table   t2  ON t1.UserID = t2.UserID
                            AND t1.BillingMonth = t2.BillingMonth - 1
WHERE       t2.UserID IS NULL
GROUP BY    t1.BillingMonth

如何运作:为每个用户LEFT JOIN在下个月内向同一位用户提供WHERE t2.UserID IS NULL。然后,我们只计算下个月有多少用户(LEFT JOIN)。

使用了

NULL,因为如果下个月用户不在那里,它将返回INNER JOIN。如果在下个月未找到用户,public void otworz(View view) throws Exception { new JSONTask().execute("http://www.filmweb.pl/serial/Biuro-2005-202887"); String tekst1 = new String(tekst.substring(10,20)); tView.setText(tekst1); } 将不会返回该行。

答案 1 :(得分:0)

这是使用while循环执行此操作的一种方法。创建临时表并在循环中插入值。然后在循环之后从临时表中select

declare @i int = 1;
IF OBJECT_ID('tempdb.dbo.#temp', 'U') IS NOT NULL
DROP TABLE #temp; 
create table #temp(monthid int,usercount int);
while @i < 12
begin
select @i+1, count(userid) 
into #temp
from table 
where BillingMonth = @i 
and userid not in (select userid from table where BillingMonth = @i+1)
set @i = @i + 1
end
select * from #temp

答案 2 :(得分:0)

您可能希望使用日期作为结算月份的数据类型,因为它会使计算更容易,并且您不会在不同年份的问题中结束,或者您的数据跨越例如11月到3月。< / p>

看起来您实际上只对每个用户的上个月感兴趣,因此可以使用row_number获取,如下所示:

select * from
(
  select UserID, BillingMonth, 
  row_number() over (partition by UserID order by BillingMonth desc) as RN
) X
where RN = 1

如果你只想要计数,你当然可以使用这个:

select BillingMonth, count(*) from
(
  select UserID, BillingMonth, 
  row_number() over (partition by UserID order by BillingMonth desc) as RN
) X
where RN = 1
group by BillingMonth

答案 3 :(得分:0)

轻松采用您开始使用的方法并仅关联子查询。它与您的查询基本相同,只是动态处理月份加一个逻辑:

select t.BillingMonth, count(t.userid) 
from <T> t
where t.BillingMonth <> '<MaxMonth>' and t.userid not in (
    select t2.userid from <T> t2
    where t2.BillingMonth = cast(cast(t.BillingMonth as int) % 12 + 1 as varchar(2))
)
group by t.BillingMonth

您不希望尝试将上个月与上个月(实际上是一年前)连接起来。但我不知道您的数据是什么样的,所以我只是添加了“MaxMonth”条件。根据当前日期或数据中的最大值,可能有更好的方法。

我将您的BillingMonth视为字符串值,就像您在上面的代码中所做的那样。此外,我正在处理您需要在12月到1月之间滚动的情况。

以上查询只返回11行。最后一个月的损耗在逻辑上为零或从数据中无法获得。