3

我正在尝试掌握 Active Record 查询界面。我有两个模型:

class Movie < ActiveRecord::Base
  has_many :datapoints
  attr_accessible :genre
end

class Datapoint < ActiveRecord::Base  
  belongs_to :movie  
  attr_accessible :cumulative_downloads, :timestamp
end

我想找到给定时间段内每种类型的增量下载。

到目前为止,我已经设法在一段时间内获得每部电影的最大和最小下载量,如下所示:

maximums = Datapoint.joins(:movie)
    .where(["datapoints.timestamp > ?", Date.today - @timespan])
    .group('datatpoints.movie_id')
    .maximum(:cumulative_downloads)

然后,这使我可以计算每部电影的增量,然后再将其汇总为每种类型的增量。

显然,这有点笨拙,我相信可以一步完成(并使用哈希条件)。我只是不知道怎么做。你能帮我吗?

非常感激!

德里克。

4

1 回答 1

3

我认为这将允许您计算每种类型的最大值:

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}
于 2012-07-08T18:27:17.623 回答