Ruby on Rails вычисляет «ранг» на основе значений базы данных? - PullRequest
1 голос
/ 11 марта 2009

Существует ли простой и быстрый способ расчета ранга поля в базе данных с использованием Ruby on Rails? Например, если у меня есть таблица math_scores, и я хотел бы найти заданный MathScore.find (: all,: condtions => ...: order => ...), то выполните итерацию по всем из них, чтобы выяснить, где результат теста падает, но должен быть более простой способ ... Любой совет?

Вот некоторая информация о схеме, это просто простая таблица:

first_name varchar (50)

фамилия varchar (50)

test_id int

оценка с плавающей точкой

Пояснение: Я предполагаю, что вопрос ближе к тому, как мне получить значение ранга при выполнении: rank = MathScore.find_by_sql («выберите количество (*) в качестве ранга из (выберите * из математических показателей, где счет> (выберите счет из высоких_счет, где test_id = 33 И first_name =« Джон »И фамилия =« Доу ») упорядочить по счету desc) as s ")

Я получаю [#<HighScore:0x6ca4724 @attributes={"rank"=>"3"}>]:Array на основе запроса, но как мне получить значение ранга?

Заранее спасибо, Бен

Ответы [ 5 ]

5 голосов
/ 11 марта 2009

Вы можете использовать именованные области действия с 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 %>
3 голосов
/ 11 марта 2009
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 голосов
/ 11 марта 2009

Я не особенно знаю Rails, но я предполагаю, что есть некоторый эквивалент для следующего примера SQL.

ВЫБЕРИТЕ СЧЕТЧИК (*) + 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-м ранге, затем следующий будет иметь 4-й ранг и т. Д. Если вам не нравится этот побочный эффект, вы можете использовать выражение WHERE, чтобы разделить их на test_id или имя и фамилия.

Это только подходящее решение для одного теста за раз. Если вы хотите оценить их все, вы можете также получить их все, набрать ORDER BY и самим их оценить.

1 голос
/ 11 марта 2009

Не уверен, какая у вас СУБД; но большинство из них поддерживают функции SQL ранга и dens_rank (оконные функции). Пример:

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
0 голосов
/ 11 марта 2009

Вы пытаетесь определить, где на кривой колокола падает тестовый балл? Вы можете попробовать свернуть свою собственную функцию для модели, используя одну из встроенных групп MySQL с помощью таких функций, как STDDEV_POP (). Вы можете видеть их здесь. С некоторой изощренной работой ног вы можете вернуть положение оценки на кривой одним вызовом в БД.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...