我们公司每个月都会为“当月客户”绘制图纸。该图基本上是基于客户当月花费多少的加权图。
目前,我正在获取客户名称及其积分数量,并通过我在网上找到的Excel随机分配器对其进行运行。每月在40多个位置单独进行操作变得很麻烦。
我要道歉,因为我已经看到了其他一些问题,但是我不能全神贯注地编写TSQL来选择随机加权获胜者。
如果单个命令可以向我输出每个位置的随机获胜者,那就太好了,但是我很难找到从哪里开始并确保正确选择加权获胜者。
期望的结果只是获奖者名单,每个地点一个。
答案 0 :(得分:0)
您可以使用累积总和来解决此类问题。这是一个相对简单的实现:
select t.*
from (select locationId, customerId, sum(sales) as sumSales,
sum(sum(sales)) over (partition by locationId) as total_sales,
(sum(sum(sales)) over (partition by locationId order by newid()) * 1.0 / sum(sum(sales)) over (partition by locationId)) as cumulative_ratio
from t
where salesdate between ? and ? -- whatever your range
group by locationId, customerId
) t
where 0.5 >= cumulative_ratio - sumSales * 1.0 / total_sales and
0.5 < cumulative_ratio;
您可以看到它在做什么。假设您在一个地点有4个客户:
l c s
1 A 1
1 B 2
1 C 3
1 D 4
然后将数据扩充为:
l c s total_sales cumulative ratio
1 A 1 10 0.1
1 B 2 10 0.3
1 C 3 10 0.7
1 D 4 10 1.0
最后的WHERE
选择累积比率和前一个值之间的0.5。它是通过从比率中减去当前行数据来实现的。
此示例显示了按字母顺序订购的客户。但是,查询将它们随机排序。 0.5是完全,完全任意的。任何值都可以,因为随机性已经内置在累积比率中。
编辑:
A,这在SQL Server 2008上不起作用。我们可以使用apply
来解决此问题,尽管代码的效率甚至更低:
with sales as (
select locationId, customerId, sum(sales) as sumSales, newid() as random
from t
where salesdate between ? and ? -- whatever your range
group by locationId, customerId
)
select t.*
from (select locationId, customerId, sum(sales) as sumSales,
ss.runningsumsales,
sum(sum(sales)) over (partition by locationId) as totalsales
from sales s cross apply
(select sum(s2.sumsales) as runningsumsales
from sales s2
where s2.locationId = s.locationId and s2.random <= s.random
) ss
where salesdate between ? and ? -- whatever your range
group by locationId, customerId
) t
where 0.5 >= (runningsumsales - sumSales) * 1.0 / total_sales and
0.5 < runningsumsales / total_sales;