2009-07-07 2 views
0

Можно ли использовать вычисления ActiveRecord, а также получить соответствующие имена полей? Например, я хотел бы найти средний возраст всех людей с различными фамилиями. В основном я хотел бы использовать:(Rails, ActiveRecord) Как использовать вычисления ActiveRecord, сохраняя при этом имена полей?

Person.average(:age, :group_by => "last_name") 

... в качестве замены

"Select last_name, AVG(age) FROM People GROUP BY last_name" 

Любые идеи?

+0

Что вы имеете в виду «получение соответствующих названий полей»? – Ethan

+0

Произвольные поля по моему выбору. –

ответ

1

Это работает практически так же, как вы описали (хотя, я думаю, вы использовали бы следующую группу: group_by) для отдельных полей. Возврат - OrderedHash, поэтому ключи будут последними именами, а значениями будет средний возраст для этой фамилии.

Поскольку любое поле, которое вы возвращаете, должно быть включено в группу, если вы хотите добавить дополнительные поля, вы можете попробовать сделать что-то немного хакерским. В Postgres, к примеру, вы можете сцепить дополнительные поля следующим образом:

Person.average(:age, :group => "first_name || ',' || last_name") 

Ключи в свою очередь будет через запятую имена и фамилии. Если вы хотите вернуть объекты ActiveRecord :: Base, вам нужно обратиться к "SELECT ..." запросам стиля.

0
Person.average(:age, :select => "last_name", :group => "last_name") 

Он возвращает хеш, где ключ является значением для имени_ставки, значение является результатом среднего расчета.

+0

Если вы указываете значение a: select в параметрах, то оно использует это вместо столбца для группы, поэтому вы получите такой запрос: SELECT avg (last_name) FROM people GROUP BY last_name – Shadwell

+0

Вы уверены? Я попробовал, и он выполнил следующий запрос: «SELECT AVG (last_name) как avg_last_name, last_name как last_name ...» –

+0

Да, это именно то, что я получил. Требование состоит в том, чтобы усредненный столбец был age not last_name. Это немного странно - есть строка кода, которая просто использует значение параметра: select вместо параметра column_name, если: select присутствует. – Shadwell

1

Чтобы вернуть какой-либо атрибут в класс, который вы усредняете, вам, вероятно, лучше использовать стандартный метод find(:all, ...) с опцией :select.

Так что ваш пример будет:

groups_of_people = Person.find(:all, 
    :select => 'avg(age) as avg_age, last_name', 
    :group => 'last_name') 

Они не являются действительно экземпляры Person тогда (хотя они будут возвращаться как таковой), но вы можете сделать:

groups_of_people.each do |g| 
    g.last_name 
    g.avg_age 
end 
Смежные вопросы