将子行计数为查询中的条件

时间:2012-04-07 08:30:12

标签: sql ruby activerecord count

我有一个包含“容量”列并且与“注册”具有has_many关系的“群组”表。我希望能够找到其入学人数少于其容量的组,因此使用ActiveRecord + Ruby我可以这样做:

Group.all.select {|g| g.enrollments.count < g.capacity }.first

但似乎应该有一种方法在SQL中执行此操作,我只是不知道如何。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

纯SQL的方法是

select groups.* from groups
    inner join enrollments on enrollments.group_id = groups.id
group by groups.id
having count(*) < capacity

或在activerecord中

Group.joins(:enrollments).group('groups.id').having('count(*) < capacity)

计数器列上带有索引的计数器缓存虽然会更快,但显然你不得在acriverecord的后面创建注册。

答案 1 :(得分:0)

可以使用:counter_cache选项。

  1. 将enrollments_count列添加到Groups表

    column :groups, :enrollments_count, :integer, :default => 0
    
  2. 设置注册&lt; counter_cache选项

    class Enrollment < ActiveRecord::Base
      belongs_to :group, :counter_cache => true
    end
    
  3. Group.where(&#34; capacity&gt; enrollments_count&#34;)。first