我认为这将允许您计算每种类型的最大值:
Movie.joins(:datapoints).where(datapoints: {timestamp: (Time.now)..(Time.now+1.year)}).group(:genre).maximum(:cumulative_downloads)
编辑 1
您可以通过几个步骤获得差异:
rel = Movie.joins(:datapoints).where(datapoints: {timestamp: (Time.now)..(Time.now+1.year)}).group(:genre)
mins = rel.minimum(:cumulative_downloads)
maxs = rel.maximum(:cumulative_downloads)
res = {}
maxs.each{|k,v| res[k] = v-mins[k]}
编辑 2
你最初的方向几乎就在那里。您所要做的就是在 SQL 中计算每部电影的差异并暂存数据,这样您就可以一次性收集数据。我确信有一种方法可以在 SQL 中完成这一切,但我不确定它是否会那么简单。
# get the genre and diff per movie
result = Movie.select('movies.genre, MAX(datapoints.cumulative_downloads)-MIN(datapoints.cumulative_downloads) as diff').joins(:datapoints).group(:movie_id)
# sum the diffs per genre
per_genre = Hash.new(0)
result.each{|m| per_genre[m.genre] += m.diff}
编辑 3
包括 select 中的 movie_id 和 group 中的流派:
# get the genre and diff per movie
result = Movie
.select('movies.movie_id, movies.genre, MAX(datapoints.cumulative_downloads)-MIN(datapoints.cumulative_downloads) as diff')
.joins(:datapoints)
.group('movies.movie_id, movies.genre')
# sum the diffs per genre
per_genre = Hash.new(0)
result.each{|m| per_genre[m.genre] += m.diff}