结合Active Record组,join,maximum&最低限度

时间:2012-07-08 16:22:59

标签: sql ruby-on-rails activerecord

我正试图掌握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)

然后,这允许我计算每部电影的增量,然后将其汇总为每种类型的增量。

显然,这有点火腿,我确信可以一步完成(并使用哈希条件)。我无法理解如何。你能帮忙吗?

非常感谢!

德里克。

1 个答案:

答案 0 :(得分: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

包括选择中的movie_id和组中的类型:

# 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}