On Rails 4. 我正在构建一个竞赛应用程序。我有三个与此用例相关的表:
提交内容 - 属性包括:
:contest_year
- 创建提交的年份:category_id
- 提交分配给的竞赛类别:division_id
- 提交分配给的竞赛部门(共五个)
分数 - 属性包括:
:user_id
- 打分的裁判ID:submission_id
- 分数绑定(bind)的提交 ID:total_score
- 裁判提供的整数作为条目的分数;通常十分之一
评委 - 属性包括:
:user_id
- 裁判的用户ID:category_id
- 裁判分配给分数的类别:division_id
- 裁判分配给分数的分区
一个提交可以有多个分数(因为有多个评委分配给它的类别/部门)。
应用程序必须做的第一件事是从各个评委给它的所有子分数中找到提交的综合最终分数。我使用 submission.rb 中的计算来执行此操作:
def calculate_final_score
self.scores.average(:total_score)
end
所以基本上,它会找到提交的所有子分数,并取这些分数的平均值来找到最终分数。这个最终分数不是提交表的更新属性,它是一个方法计算结果。
现在,这是我的问题所在。我需要找到一种方法来计算与具有相同 :contest_year
、 的其他提交相比提交的排名:category_id
, 和 :division_id
通过比较上面的最终得分计算。当提交的最终分数相同(平局)时,排名系统必须给出相同的排名。
tl;dr,我需要这样的排名行为(样本提交表):
----------------------------------------------------------------------
| ID | Contest Year | Division ID | Category ID | Final Score | Rank |
|--------------------------------------------------------------------|
| 1 | 2013 | 1 | 1 | 10 | 1 |
|--------------------------------------------------------------------|
| 2 | 2013 | 1 | 1 | 10 | 1 |
|--------------------------------------------------------------------|
| 3 | 2013 | 1 | 1 | 8 | 2 |
|--------------------------------------------------------------------|
| 4 | 2013 | 1 | 1 | 6 | 3 |
|--------------------------------------------------------------------|
| 4 | 2013 | 1 | 1 | 5 | 4 |
|--------------------------------------------------------------------|
| 5 | 2013 | 2 | 1 | 8 | 1 |
|--------------------------------------------------------------------|
| 6 | 2014 | 1 | 2 | 9 | 1 |
|--------------------------------------------------------------------|
| 7 | 2014 | 1 | 2 | 7 | 2 |
----------------------------------------------------------------------
此排名信息将放置在我的 Active Admin 提交的索引表页面中(也作为 CSV 表输出的一部分)。
最佳答案
我不太熟悉 Rails(或 Ruby)。但是在我们的 Django 应用程序中,我们遇到了类似的情况,我们需要计算一些计算数据的排名。由于我们使用 PostgreSQL 作为数据库后端,因此我们使用 Postges 的窗口函数(http://www.postgresql.org/docs/9.1/static/functions-window.html、http://www.postgresql.org/docs/9.1/static/functions-window.html、http://www.postgresql.org/docs/9.1/static/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS)进行排名计算。以下是一个示例 PostgresSQL 查询,它可以产生您的问题所需的结果。
sql_query = %Q{SELECT
*, dense_rank() OVER (
PARTITION BY contest_year, category_id, division_id
ORDER BY final_score DESC
)
FROM (
SELECT
Submissions.id,
Submission.contest_year AS contest_year,
Submission.category_id AS category_id,
Submission.division_id AS division_id,
AVG(Scores.total_score) AS final_score
FROM Submissions
INNER JOIN Scores ON (Submissions.id = Scores.submission_id)
GROUP BY
Submissions.id,
Submission.contest_year,
Submission.category_id,
Submission.division_id
) AS FinalScores}
submissions_by_rank = Submission.find_by_sql(sql_query)
注意:如果您想以特定方式对结果进行排序,则需要在查询中添加 ORDER BY
子句。
关于ruby-on-rails - Ruby on Rails - 计算排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23617426/