我有User
一个has_many
messages
。我需要创建一个查询
'Get me all users who's (message.opened == false) count < 3'
现在,我正在使用User.all
,遍历所有用户,并手动计数。我知道这不是很有效,可以在一个查询中完成,但我是 SQL/ActiveRecord 的新手,所以在这里需要一些帮助。谢谢
我有User
一个has_many
messages
。我需要创建一个查询
'Get me all users who's (message.opened == false) count < 3'
现在,我正在使用User.all
,遍历所有用户,并手动计数。我知道这不是很有效,可以在一个查询中完成,但我是 SQL/ActiveRecord 的新手,所以在这里需要一些帮助。谢谢
尝试这个
User.includes(:messages).group('users.id').having('SUM(IFNULL(messages.opened = 0, 1)) < 3')
它至少适用于 MySQL,并且假设您的布尔值 true 在数据库中为 1。
编辑我已经扭转了条件
PS IFNULL
是否messages.opened
可以处理NULL
假设 Rails 3 语法。您可以执行以下操作:
User.joins(:messages).where(:messages => {:opened => false}).group(:user_id).having("COUNT(messages.id) < 3)
这应该有效:
User.includes(:messages).group("users.id").where("messages.opened = 0").having("count(messages.id) < 3")
这将创建两个查询,一个用于分组查询,另一个用于通过连接预先加载结果用户和消息。
这是您的问题的解决方案
User.includes(:messages).group("users.id").where("messages.opened = 0").having("count(messages.id) < 3")
但你还能做的就是为此创建一个范围
scope :not_opened_less_three_count, includes(:messages).group("users.id").where("messages.opened = 0").having("count(messages.id) < 3")
然后你可以在任何你需要的地方使用它,如下所示
User.not_opened_less_three_count