寻找购买总和

时间:2013-02-06 10:43:25

标签: ruby-on-rails ruby sum

每个User都有许多Purchases。我想找到前28天的每一天的总和。

t1 = Time.now - (28.days)
t2 = Time.now
@dailysum = Array.new(29)
(0..29).each do |i|
  @dailysum[i] = @user.purchases.where(:created_at => (Time.now-(i.day))..(Time.now-((i-1).days))).sum(:amount)
end

这有效,但我确信有更好的方法可以解决这个问题。有什么建议吗?

3 个答案:

答案 0 :(得分:2)

您需要将:group选项传递给sum。 :group选项的值因您的数据库而异。我将提供一个pg和mysql版本。

# purchases.rb
def self.recent(num)
  where('created_at > ?', num.days.ago
end

# PG version
@user.purchases.recent.sum(:amount, group: "DATE_PART('year', purchases.created_at) || '-' || DATE_PART('month', purchases.created_at) || '-' || DATE_PART('day', purchases.created_at)")

# mysql version
@user.purchases.recent.sum(:amount, group: "DATE(purchases.created_at)")

这将导致哈希,其中键是日期,值是购买的总和。

与过去28天内每天查询相比,这将减少27次查询

答案 1 :(得分:2)

/!\见其他(更好)答案

此答案将计算过去28天的整个购买总和

请阅读我的其他答案,以计算每个过去28天的总和。

我将这个在网上留给那些对此感兴趣的人。


@user.purchases
    .where('created_at > ?', 28.days.ago) # retrieve all purchases within the last 28 days
    .sum(:amount)                         # get the sum of the amount column

如果你想使用@andy提出的范围:

# in purchase.rb
scope :recent, ->(d) { where('created_at > ?', d.days.ago) }

# then in you controller
@user.purchases
  .recent(28)          # retrieve all purchases within the last 28 days
  .sum(:amount)        # get the sum of the amount column

答案 2 :(得分:0)

现在我已经更好地理解了这个问题,这是第二次尝试。

这很难脱离背景。

user.purchases
  .where('created_at > ?', 28.days.ago)
  .group_by { |p| p.created_at.to_date }
  .collect { |d, ps| [d, ps.sum { |p| p.amount }]  }

那应该返回一个数组数组,其中包含该日期的日期和金额总和:

[
  ["Mon, 28 Jan 2013", 137],
  ["Tue, 29 Jan 2013", 49]
  ["Wed, 30 Jan 2013", 237]
]