model entry.rb
def self.calculate(year, month, id)
where(':id = entries.user_id', {
:id => id
}).
where('entries.date <= :last_day', {
:last_day => Date.new(year, month, 1).at_end_of_month
}).
select('sum(case when joint = "f" then amount_calc else 0 end) as sum_single,' +
'sum(case when joint = "t" then amount_calc else 0 end) as sum_joint,' +
'sum(case when compensation = "t" then amount_calc else 0 end) as sum_compensation')
end
The query delivers three sums for a particular user and all entries up to the given month. Works fine so far.
What I really would need next is exactly the s开发者_C百科ame but with one value for each month (and months in different years have to be in a different group). The code needs to work with both SQLite and PostgreSQL.
{ Additional question: is it possible to get the grouping and the overall sums like in my original code above in ONE query? I believe it is not possible... }
SQLite
def self.calculate(year, month, id)
where(':id = entries.user_id', {
:id => id
}).
where('entries.date <= :last_day', {
:last_day => Date.new(year, month, 1).at_end_of_month
}).
select('sum(case when joint = "f" then amount_calc else 0 end) as sum_single,' +
'sum(case when joint = "t" then amount_calc else 0 end) as sum_joint,' +
'sum(case when compensation = "t" then amount_calc else 0 end) as sum_compensation').
group("strftime('%Y-%m', created_at)")
end
Postgre something like this (I've never used this db)
def self.calculate(year, month, id)
where(':id = entries.user_id', {
:id => id
}).
where('entries.date <= :last_day', {
:last_day => Date.new(year, month, 1).at_end_of_month
}).
select('sum(case when joint = "f" then amount_calc else 0 end) as sum_single,' +
'sum(case when joint = "t" then amount_calc else 0 end) as sum_joint,' +
'sum(case when compensation = "t" then amount_calc else 0 end) as sum_compensation').
group("EXTRACT(YEAR FROM TIMESTAMP created_at)||EXTRACT(MONTH FROM TIMESTAMP created_at)")
end
So you should firstly check what adapter is used and then use one of those queries
精彩评论