Ако имате връзка между Review
и Audio
след това нещо като това:
revs = Review.joins(:audios)
.group('style_id')
.select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')
Това ще даде списък с Review
екземпляри в revs
и тези екземпляри ще имат допълнителен avg_col1
и avg_col2
методи за достъп до средните стойности, както и обичайния style
/style_id
методи, но другите методи за достъп до колони, които Review
би предложил обикновено ще доведе до изключения.
Ако не сте настроили асоциациите, тогава можете да направите JOIN ръчно:
revs = Review.joins('join audios on reviews.consumer_id = audios.consumer_id')
.group('style_id')
.select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')
Ако всичко, от което се нуждаете, са само необработените данни без цялото обвиване на ActiveRecord и допълнителни разходи, тогава можете да изпълните необработения SQL и да го хеширате ръчно, като използвате select_rows
:
Review.connection.select_rows(%q{
select r.style_id, avg(a.col1), avg(a.col2')
from reviews r
join audios a on r.consumer_id = a.consumer_id
group by r.style_id
}).map do
{ :style_id => r.shift, :avg_col1 => r.shift.to_f, :avg_col2 => r.shift.to_f }
end
Това ще ви даде масив от хешове. Можете дори да опростите този подход, като използвате Struct
за създаване на прости класове за обвиване на данни:
c = Struct.new(:style_id, :avg_col1, :avg_col2)
revs = Review.connection.select_rows(%q{...}).map do |r|
c.new(r.shift, r.shift.to_f, r.shift.to_f)
end
PS:Не използвайте неявни условия за присъединяване във вашия SQL, това е просто бърз и лесен начин за създаване на кръстосани продукти, използвайте изрични условия за присъединяване:
SELECT ...
FROM reviews JOIN audios ON reviews.consumer_id = audios.consumer_id
GROUP BY style_id