每个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
这有效,但我确信有更好的方法可以解决这个问题。有什么建议吗?
答案 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]
]