这真让我大吃一惊。我创建了一个联盟,我根据参赛者数量的最小和最大位置来定义奖品,即:
LeagueSizeID LeagueSizeMin LeagueSizeMax
1 1 24
2 25 49
3 500 999
这涉及一个定义每个联赛的支出的表,这是leaguesizeid 3的例子
LeaguesizeID PositionMin PositionMax WinPerc
3 1 1 22.00
3 2 2 10.00
3 3 3 7.00
3 4 4 6.00
3 5 5 5.00
3 6 6 4.00
3 7 7 3.50
3 8 8 3.00
3 9 9 2.50
3 10 10 2.00
3 11 20 1.00
3 21 30 0.50
我采取的方法是循环每个位置并获得与该位置匹配的参赛者。我的问题是可以有联合赢家。如果有联合获胜者,那么第二名奖金需要考虑。所以对于以下结果:
UserID Position Prize
1 1 22.0%
2 2 10
3 3 6.5 // joint here so takes position 3 and 4
4 3 6.5 // and splits prize
5 4 5 % // this is now position 5
我正在使用DenseRank()是SQL来排序位置但是我可能需要将其更改为Rank(),除非有人能指出我在算法的正确方向上从数据库对象驱动吗?
提前致谢!
答案 0 :(得分:0)
我希望创建两个中间结果集。首先rank_bounds
。这具有该等级的用户ID,等级和关系数。第二个是exploded_payout
。每个支付位置都有一行,而不是累积到最小和最大位置。一旦你有了这个,你可以很容易地获得支付百分比。
我使用常用的表格表达式(并简化并填写了一些缺少的表格详细信息)将它们全部放在一起:
with ranks as (
select
UserID,
rank() over (order by Score desc) rk
from
UserGameScores
where
GameID = 1
), rank_bounds as (
select
UserID,
rk Position,
count(1) over (partition by rk) as TieCount
from
ranks
), n as (
select
row_number() over (order by number) rn
from
-- if you have lots of payout lines, you might need more numbers than this
master..spt_values
), exploded_payout as (
select
n.rn as Position,
p.WinPerc
from
Payout p
inner join
n
on p.PositionMin <= n.rn and p.PositionMax >= n.rn
) select
UserId,
avg(winperc)
from
exploded_payout xp
inner join
rank_bounds rb
on xp.Position >= rb.Position and
xp.Position < rb.Position + rb.TieCount
group by
UserId;
如果你想在结果集中得到排名,你需要将最后一位放入CTE并再次加入排名表。
虽然SQL有点难以理解。我不确定程序方法会简单得多。此外,SQL具有很好的属性,可以很容易地一次扩展到所有游戏:)