2012-09-30 65 views
2

我有以下型號Rails應用程序:排名位置

  • 用戶
  • 投注

用戶有many_bets和投注belongs_to的用戶。每個投注都有一個Profitloss值,它說明用戶在該投注中贏/輸的程度。

所以要計算多少特定的用戶已經通過以下方式通過他的賭注贏得總我循環:

User.bets.sum(:profitloss) 

我想顯示他的排名相比,所有的其他用戶,這可能是這個樣子:

「你總排名:第37位」

要做到這一點我需要總結每個用戶的整體獎金,並找出在哪個位置當前用戶是。

我怎麼做,如何做到這一點,所以它不超載的服務器:)

謝謝!

回答

3

您可以嘗試類似的東西來

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

,然後在出現的「用戶」(不是真正的用戶,他們只有兩個有意義的屬性,它們的ID和accumulated屬性與總和)的列表中搜索,對應於當前的那個。

在任何情況下,要獲得單個用戶的位置,您必須計算所有用戶的'accumulated,但至少這只是一個查詢。更好的是,您可以在用戶模型中存儲累計值,並查詢它的排名。

+0

我想我與誰具有最高後排序的用戶數組利潤損失。我如何在這個數組中找到一個特定的用戶並查看他擁有哪個位置。像第37位一樣。 – Twiddr

+1

對後期輸入反應到你的答案對不起 - 我的妻子剛生下的一天,所以我一直在忙:) – Twiddr

+1

我用這種方法用耙子任務結合.. – Twiddr

1

如果您有大量的用戶和投注,您將無法「按需」計算和分類每個用戶的全局利潤,所以我建議您使用您定期(一次)計劃的rake task一天,每一小時,等...)

User模型添加列position,得到所有用戶的列表,計算其全球profitloss,排序與他們profitloss用戶列表,最後更新position每個User的屬性及其在列表中的位置。

+0

我當然明白你的意思,我考慮使用rake任務來計算這些排名,然後只是重新計算它們每隔一小時左右。它們對應用程序並不重要,可以輕鬆一個小時。 – Twiddr

1

最好的辦法是在您的數據庫中保留一個預先計算的總數,或者在user模型本身或與user具有1:1關係的單獨模型中。如果您不這樣做,則您必須始終爲所有用戶計算總和以獲得他們的評分,這意味着在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; 
+1

如果'User'模型有一列'total_profit_loss',用戶'u'簡直是'User.where的位置( 'total_profit_loss>?',u.total_profit_loss).Count之間+ 1' – Baldrick

+0

我看到你在哪裏與此打算,但SQL對我來說是有點太複雜(我缺少一些SQL技能).. – Twiddr