Als je een verband hebt tussen Review
en Audio
dan zoiets als dit:
revs = Review.joins(:audios)
.group('style_id')
.select('style_id, avg(col1) as avg_col1, avg(col2) as avg_col2')
Dat geeft een lijst met Review
instanties in revs
en die instanties hebben extra avg_col1
en avg_col2
methoden voor toegang tot de gemiddelden en de gebruikelijke style
/style_id
methoden maar de andere kolomaccessormethoden die Review
normaal zou aanbieden, zullen uitzonderingen veroorzaken.
Als je de koppelingen niet hebt ingesteld, kun je de JOIN handmatig doen:
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')
Als alles wat je nodig hebt alleen de onbewerkte gegevens zijn zonder alle ActiveRecord-wikkeling en overhead, dan kun je de onbewerkte SQL uitvoeren en deze met de hand hashen met behulp van 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
Dat zou je een array van hashes geven. Je zou die aanpak zelfs kunnen vereenvoudigen met Struct
om eenvoudige gegevenswrapperklassen te maken:
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:gebruik geen impliciete join-voorwaarden voor uw SQL, dat is slechts een snelle en gemakkelijke manier om cross-producten te produceren, gebruik expliciete join-voorwaarden:
SELECT ...
FROM reviews JOIN audios ON reviews.consumer_id = audios.consumer_id
GROUP BY style_id