Rails3:左连接聚合计数 - 如何计算?

man*_*ire 1 sql activerecord ruby-on-rails-3

在我的应用程序的用户注册活动,这属于一个.该登记在托管登记模型,其中有一个叫布尔域" 出席 ".

我正在尝试生成排行榜并需要知道:每个用户的注册总数,以及每个单独事件流中用户注册的计数.

我正在尝试这个(在User.rb中):

# returns an array of users and their attendence count
def self.attendance_counts
    User.all( 
      :select => "users.*, sum(attended) as attendance_count", 
      :joins => 'left join `registrations` ON registrations.user_id = users.id', 
      :group => 'registrations.user_id', 
      :order => 'attendance_count DESC'
    )
end
Run Code Online (Sandbox Code Playgroud)

当我在数据库中运行时,生成的SQL仅用于返回每个用户的总有人值,但返回的所有内容都是Rails中的用户记录.

我即将放弃并将每个流的counter_cache硬编码(它们相当固定)到User表中,只要注册模型保存的有人参与属性发生变化,就会手动更新.

不过,我真的很好奇如何执行这样的查询.在计算有关系的记录的统计数据和报告时,它必须始终出现.

非常感谢您的时间和考虑.提前致谢.

Chr*_*ley 6

首先,作为样式和轨道功能的几点,可以帮助您构建数据库查询.

1)你最好把它写成范围而不是方法,即

scope attendance_counts, select("users.*, sum(attended) as attendance_count").joins(:registrations).group('registrations.user_id').order('attendance_count DESC')
Run Code Online (Sandbox Code Playgroud)

2)最好不要在你实际需要它之前调用所有/ find/first你所建立的查询(即在控制器或视图中).这样,如果您决定在以后对数据库查询实施操作/片段缓存,则在向用户提供缓存的操作/片段时将不会调用它.

3)Rails有一系列功能来帮助聚合数据库数据.例如,如果您只想要用户的ID和有人参与的总和,您可以使用类似下面的代码:

Registrations.group(:user_id).sum(:attended)
Run Code Online (Sandbox Code Playgroud)

其他功能包括count,avg,minimum,maximum

最后,在回答您的问题时,rails将为您创建一个属性,以便您访问查询的选择部分中的任何自定义字段的值.例如

@users = User.attendance_counts
@users[0].attendance_count # The attendance count for the first user returned by the query
Run Code Online (Sandbox Code Playgroud)