Rails ActiveRecord中的组查询

时间:2014-06-30 20:29:08

标签: sql ruby-on-rails activerecord group-by

我试图在具有以下结构的表上使用Rails中的ActiveRecord进行(sql查询)分组:

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)

我希望查询返回特定用户每个特定月份的computed_hours和computed_minutes总和:

因此,例如,对于user_id = 2,我希望它返回

2014-06-02 4.5(computed_hours和computed_minutes合计) 2014-06-05 3.25 ......

如果上面的表被称为billables并且相应模型的名称是Billable,那怎么能用ActiveRecord写呢?

提前感谢您的时间。

1 个答案:

答案 0 :(得分:0)

假设您将user_id和month(作为日期的一部分)作为参数传递,这应该有效:

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)

然后,对于每个@billable生成的行,您将拥有:

@billable.user_id
@billable.total_hours
@billable.total_minutes

<强> 更新

在您使用Postgres的情况下,这将产生一个您无法轻易覆盖的无法想象的错误。

生成的SQL将尝试按"billable"."id"对查询进行排序,这将导致Postgres也需要使用GROUP BY "billable"."id"

您可以绕过此行为,只需要通过请求NO ORDERING或按您选择的字段排序(在这种情况下应为work_date)。

因此,解决方案需要将最后一行更改为:

         group(:work_date).order(false)

         group(:work_date).order(:work_date)