Reputation: 2459
I am trying to do a group by (sql query) using ActiveRecord in Rails on a table with the following structure:
id (integer)
user_id (integer, foreign key from the users table)
work_date (date, e.g., 2014-06-02)
computed_hours (integer, e.g., 4)
computed_minutes (integer, e.g., 30)
I want the query to return the sum of computed_hours and computed_minutes totaled for a specific user for each day of a particular month:
So, for instance, say for, user_id = 2, I would like it to return
2014-06-02 4.5 (computed_hours and computed_minutes totaled) 2014-06-05 3.25 ......
How could this be written in ActiveRecord assuming that the table above is called billables and that the corresponding model's name is Billable?
Thanks in advance for your time.
Upvotes: 0
Views: 2009
Reputation: 5740
Assuming you pass user_id and month (as part of a date) as parameters, this should work:
userid = params[:user_id]
date_start = Date.parse(params[:date]).at_beginning_of_month - 1.days
date_end = Date.parse(params[:date]).at_end_of_month + 1.days
Billable.all.
select('work_date,
sum(computed_hours) as total_hours,
sum(computed_minutes) as total_minutes').
where( 'user_id = ? and (work_date > ? and work_date < ?)',
userid, date_start, date_end).
group( :work_date)
Then, for each @billable
of the resulting rows you'll have:
@billable.user_id
@billable.total_hours
@billable.total_minutes
UPDATE:
In the likely event that you are using Postgres, this will produce an unthinkable error which you can easily override.
The resulting SQL will try to order the query by "billable"."id"
which will result in Postgres
requiring to use GROUP BY "billable"."id"
as well.
You can bypass this behaviour, simply by requesting NO ORDERING or ordering by a field of your choice (should be in this case work_date
).
Thus, the solution would require changing the last line to:
group(:work_date).order(false)
or
group(:work_date).order(:work_date)
Upvotes: 0