Ruby on Rails基于数据库值计算“排名”?

时间:2009-03-11 01:13:35

标签: sql ruby-on-rails database

使用Ruby on Rails有一种简单快捷的方法来计算数据库中字段的等级吗?例如,如果我有一个math_scores表,并且想要找到给定的MathScore.find(:all,:condtions => ...:order => ...),那么遍历所有这些表来查找考试成绩下降的地方,但必须有一个更直接的方式......任何建议?

以下是有关架构的一些信息,它只是一个简单的表格:

first_name varchar(50)

last_name varchar(50)

test_id int

得分浮动

澄清: 我想通过问题更接近于我在执行时如何检索排名值: rank = MathScore.find_by_sql(“select count(*)as rank from(select * from math_scores where score>(从high_scores中选择得分,其中test_id = 33 AND first_name ='John'AND last_name ='Doe')order by score desc )作为s“)

我根据查询获得[#<HighScore:0x6ca4724 @attributes={"rank"=>"3"}>]:Array,但如何获得排名值?

提前致谢, 本

5 个答案:

答案 0 :(得分:5)

你可以使用named scopes和Rails 2.2来帮助解决这个问题,例如

class MathScore
  named_scope :passed, :conditions => {:score => 60..100 }
  named_scope :failed, :conditions => {:score => 0..59}
end

这将允许您在控制器中执行以下操作:

@passing_scores = MathScore.passed
@failing_scores = MathScore.failed

因此,您可以在视图中迭代它们。


回应你的澄清(在erb中):

<% your_array.each do |hs| %>
  <%= hs.rank %>
<% end %>

答案 1 :(得分:3)

sql = "select count(*) as rank from (select * from math_scores where score > (select score from high_scores where test_id = 33 AND first_name = 'John' AND last_name = 'Doe') order by score desc) as s"
rank = MathScore.find_by_sql(sql)[0].rank

答案 2 :(得分:2)

我不是特别了解Rails,但我假设有以下SQL示例的等价物。

SELECT COUNT(*)+将在相关行之前的所有行中的1个。

例如,要获得您知道其得分的项目的等级为75.0:

SELECT COUNT(*) + 1 as [rank] from my_table
    WHERE score > 75.0

如果您不知道该项目的分数,但您知道其他识别信息:

SELECT COUNT(*) + 1 as [rank] from my_table
    WHERE score > (SELECT score FROM my_table WHERE test_id = 123)

这具有为具有相同分数但仍然正确分发的测试分配相同等级的副作用。因此,您可能在1级获得一个分数,然后在2级中获得两个分数,然后在第2级中获得等级4,等等。如果您不喜欢这种副作用,您可以使用WHERE子句来区分它们test_id或名字和姓氏。

这只是一次一个测试的合适解决方案。如果你想对它们进行排名,你可以将它们全部取出,ORDER BY得分,并自己排名。

答案 3 :(得分:1)

不确定您拥有什么DBMS;但大多数支持rank和dense_rank SQL函数(窗口函数)。例如:

SQL> select ename,sal,
  2   row_number()
  3     over (order by sal desc)rn,
  4   rank()
  5     over (order by sal desc)rnk,
  6   dense_rank()
  7     over (order by sal desc)drnk
  8   from emp
  9  order by sal desc
 10  /

ENAME    SAL   RN   RNK   DRNK
-----   ----   --   ---   ----
 KING   5000    1     1      1
 FORD   3000    2     2      2
SCOTT   3000    3     2      2
JONES   2975    4     4      3
BLAKE   2850    5     5      4
CLARK   2450    6     6      5

答案 4 :(得分:0)

您是否正在尝试确定测试分数在钟形曲线中的位置?您可以尝试使用MySQL的内置组之一通过STDDEV_POP()等函数为模型滚动自己的函数。你可以看到它们here.通过一些花哨的步法,你可以通过一次调用db来返回曲线上的等级位置。