3

次のモデルの Rails アプリケーションがあります。

  • ユーザー
  • ベット

ユーザーは many_bets を持っており、Bets belongs_to ユーザーです。すべてのベットには、ユーザーがそのベットでどれだけ勝ったか負けたかを示すプロフィットロス値があります。

したがって、特定のユーザーが全体でどれだけ勝ったかを計算するには、次の方法で彼の賭けを繰り返します。

 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合計の属性の 2 つの意味のある属性しかありません)、現在のユーザーに対応するものを探します。

いずれにせよ、1 人のユーザーの位置を取得するには、すべてのユーザーの を計算する必要がありますaccumulatedが、少なくともこれは 1 つのクエリにすぎません。さらに良いことに、累積値をユーザー モデルに格納し、ランキングのためにクエリを実行できます。

于 2012-09-30T20:14:16.227 に答える
1

多数のユーザーとベットがある場合、各ユーザーの全体的な利益損失を「オンデマンド」で計算してソートすることはできません。そのため、定期的に (1 日 1 回、毎時など...)

モデルに列positionを追加しUser、すべてのユーザーのリストを取得し、グローバルな利益損失を計算し、ユーザーのリストを利益損失で並べ替え、最後にリスト内の位置でposition各ユーザーの属性を更新します。User

于 2012-09-30T20:18:27.703 に答える
1

userこれを行う最善の方法は、モデル自体、または と 1:1 の関係を持つ別のモデルのいずれかで、事前に計算された合計をデータベースに保持することuserです。これを行わないと、評価を取得するために常にすべてのユーザーの合計を計算する必要があります。つまり、テーブルでの完全なテーブル操作を意味しbetsます。とはいえ、このクエリは望ましい結果を提供します。合計が同じ人が複数いる場合は、両方とも評価 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 に答える