2012-07-26 132 views
3

我有一张捐款表,我正在计算每月的总金额。对于没有没有任何捐款个月,我想返回的结果为0。计算月份统计

这里是我当前的查询:

Donation.calculate(:sum, :amount, :conditions => { 
    :created_at => (Time.now.prev_year.all_year) }, 
    :order => "EXTRACT(month FROM created_at)", 
    :group => ["EXTRACT(month FROM created_at)"]) 

返回:

{7=>220392, 8=>334210, 9=>475188, 10=>323661, 11=>307689, 12=>439889} 

任何想法如何抢空几个月?

回答

4

通常情况下,您将加入日历表(或PostgreSQL中的generate_series)以获取缺失的月份,但使用Rails最简单的方法是将结果合并到零散列表中;像这样:

class Donation 
    def self.by_month 
    h = Donation.calculate(:sum, :amount, :conditions => { 
     :created_at => (Time.now.prev_year.all_year) }, 
     :order => "EXTRACT(month FROM created_at)", 
     :group => ["EXTRACT(month FROM created_at)"]) 
    Hash[(1..12).map { |month| [ month, 0 ] }].merge(h) 
    end 
end 

然后只需调用类方法h = Donation.by_month即可获得结果。

+0

哇,这正是我所期待的。万分感谢! – tbrooks 2012-07-26 19:12:07

2

除了亩太短的回答,在3.2.12的Rails并没有为我工作,ActiveRecord的返回键为字符串:

h = Donation.calculate(:sum, :amount, :conditions => { 
    :created_at => (Time.now.prev_year.all_year) }, 
    :order => "EXTRACT(month FROM created_at)", 
    :group => ["EXTRACT(month FROM created_at)"]) 

将返回:

{"7"=>220392, "8"=>334210, "9"=>475188, "10"=>323661, "11"=>307689, "12"=>439889} 

所以当我把散列合并为零时:

{1=>0, 2=>0, 3=>0, 4=>0, 5=>0, 6=>0, 7=>0, 8=>0, 9=>0, 10=>0, 11=>0, 12=>0, "7"=>220392, "8"=>334210, "9"=>475188, "10"=>323661, "11"=>307689, "12"=>439889} 

小修正(to_s):

Hash[(1..12).map { |month| [ month.to_s, 0 ] }].merge(h)