Reputation: 2504
I'm try to save some precious millisecond in a query.
I have a stats table and I'm calculating the average value of some records grouped by a key
Activity.group(:company_id).average(:completed_courses)
Everything is ok, but I need also the average on other columns of the same table (:readed_news, :logins, etc
)
Is there a way to get all the averages with a single query?
I'm using Postgres
Upvotes: 0
Views: 1235
Reputation: 11033
Use scopes or class methods on you model:
class Activity < ActiveRecord::Base
self.average_company
group(:company_id).average(:completed_courses)
end
self.average_readed_news
group(:readed_news).average(:completed_courses)
end
end
then call:
Activity.average_company
Actvitity.average_readed_news
You could then try to merge scopes
Activity.average_company.merge(Activity.average_readed_news)
Look at the documentation here: http://guides.rubyonrails.org/active_record_querying.html
Upvotes: 0
Reputation: 139
You can write select.
Activity.group(:company_id)
.select('AVG(completed_courses) as avg_completed_courses,
AVG(readed_news) as avg_readed_news,
AVG(logins) as avg_logins')
Also, you can write method for generating select expression:
def select_exp(attrs)
attrs.sum { |attr| ("AVG(#{attr}) as avg_#{attr},") }.chop
end
Activity.group(:company_id)
.select select_exp(%w(completed_courses readed_news logins))
Upvotes: 2
Reputation: 2659
You can use single field on average
method but you can do this
activities = Activity.group(:company_id)
completed_courses = activities.average(:completed_courses)
readed_news = activities.average(:readed_news)
etc..
Hope this will help you.
Upvotes: 0