3

我有一个具有以下模型的 Rails 应用程序:

  • 用户
  • 赌注

用户拥有 many_bets 和 Bets belongs_to User。每个投注都有一个利润损失值,表明用户在该投注中赢/输了多少。

因此,为了计算特定用户总共赢得了多少,我通过以下方式循环他的投注:

 User.bets.sum(:profitloss)

我想向用户展示他与所有其他用户相比的排名,可能看起来像这样:

“你的综合排名:第37位”

为此,我需要总结每个用户的总奖金,并找出当前用户的位置。

我该怎么做以及怎么做,所以它不会使服务器超载:)

谢谢!

4

3 回答 3

4

你可以尝试类似的东西

User.join(:bets).
    select("users.id, sum(bets.profitloss) as accumulated").
    group("users.id").
    order("accumulated DESC")

然后在“用户”的结果列表中搜索(不是真正的用户,他们只有两个有意义的属性,他们的 ID 和一个accumulated带有总和的属性),寻找与当前用户对应的一个。

无论如何,要获得单个用户的位置,您必须计算所有用户的位置accumulated,但至少这只是一个查询。更好的是,您可以将累积值存储在用户模型中,并仅查询它以进行排名。

于 2012-09-30T20:14:16.227 回答
1

如果你有大量的用户和投注,你将无法“按需”计算和排序每个用户的全局利润损失,所以我建议你使用你定期安排的rake 任务(每天一次,每小时等...)

position在模型中添加一列User,获取所有用户的列表,计算他们的全局利润损失,根据利润损失对用户列表进行排序,最后根据他们在列表中的位置更新position每个用户的属性。User

于 2012-09-30T20:18:27.703 回答
1

最好的方法是在user模型本身或与user. 如果您不这样做,则必须始终计算所有用户的总和才能获得他们的评分,这意味着对bets表进行全表操作。这就是说,这个查询会给你想要的结果,如果超过 1 人的总数相同,它将都算作评分 X:

select id, (select count(h.id) from users u inner join 
(select user_id, sum(profitloss) as `total` from bets group by user_id) b2
on b2.user_id = u.id, (select id from users) h inner join
(select user_id, sum(profitloss) as `total` from bets group by user_id) b 
on b.user_id = h.id where u.id = 1 and (b.total > b2.total)) 
as `rating` from users where id = 1;

您将需要插入user.id查询where id = X

如果您向表中添加一列以user跟踪其总数,则查询会更简单一些,在此示例中,列名是total_profit_loss

select id, total_profit_loss, (select count(h.username)+1 from users u, 
(select username, score from users) h 
where id = 1 and (h.total_profit_loss > u.total_profit_loss)) 
as `rating` from users where id = 1;
于 2012-09-30T20:21:57.590 回答