2

そのため、同じプレーヤーで複数の試合が行われる可能性があるトーナメントの結果テーブルがあります。

したがって、いくつかのサンプルデータは次のようになります。

結果

Player_ID | Match_ID|Win|Elapsed_Time|etc..
1         |    1    |T  | 1:00       |etc..
2         |    1    |F  | 1:00       |etc..
1         |    2    |T  | 3:00       |etc..
3         |    2    |F  | 3:00       |etc..

各プレーヤーに対してTrueに設定されているWinフィールドをカウントし、そのカウントフィールドでグループ化するスコープを準備したいと思います。

したがって、擬似コードは次のようになります...

scope:most_wins、:all、:order_by => "Count(Player Wins)"

これは可能ですか、それともデータベース構造を再考する必要がありますか?

4

1 に答える 1

2

何よりもまず:名前付きスコープは死んでいる

次のことをお勧めします。

class Players < ActiveRecord::Base
  ....
  def self.with_win_count
    #inner join if you want to filter out those who doesn't have any match, otherwise is should be left outer 
    joins("inner join (select Player_ID, count(Match_ID) as win_count from Results where Win = true group by Player_ID) t on (t.Player_ID = Player.ID)")
  end
end

#somewhere in controller you would do
best_players = Player.with_win_count.where("win_count > ?", [10]).order("win_count DESC")

結果テーブルに含める場合:

class Results < ActiveRecord::Base
  ....
  def self.with_win_count
    joins("inner join (select Player_ID, count(Match_ID) as win_count from Results where Win = true group by Player_ID) t on (t.Player_ID = Results.Player_ID)")
  end
end

これはうまくいくでしょうが、私はそれが少し醜いと思います。

また、ネストされたクエリで条件付きカウントが必要な場合、簡単な方法は次のようになります。

class Players < ActiveRecord::Base
  ....
  def self.with_match_count(conditions)
    #inner join if you want to filter out those who doesn't have any match, otherwise is should be left outer 
    joins("inner join (select Player_ID, count(Match_ID) as match_count from Results where #{conditions} group by Player_ID) t on (t.Player_ID = Player.ID)")
  end
end
some_players = Player.with_match_count("Win = true").where("match_count > ?", [10]).order("match_count DESC")

!!! conditions引数がユーザー入力から直接構築される場合は、SQLインジェクションが発生しやすいことに注意してください。

于 2012-05-18T22:56:43.497 に答える