表结构是
userID - 唯一ID
结算月 - 支付账单的月份
我拥有的数据为1年或12个月
我必须计算每个月离开的用户总数。
提前致谢。
答案 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行。最后一个月的损耗在逻辑上为零或从数据中无法获得。