rails 4复杂的SQL范围

时间:2013-11-03 16:33:32

标签: sql ruby-on-rails ruby-on-rails-3 postgresql ruby-on-rails-4

我有Users的模型has_many EventLogs

我想创建一个范围,该范围将由具有最多事件日期的人订购用户。

scope :highest_completed_events, .....

如何计算状态为2的EventLog数量,然后对发生此类事件最多的用户进行排序。

User.joins(:event_logs).where("event_logs.status_id = 2")#... COUNT, then ORDER BY

希望这是有道理的。

2 个答案:

答案 0 :(得分:3)

这是一个您可以执行的查询,以便根据他们拥有的事件数量来排序您的用户:

@users = User.
  select("users.*, COUNT(event_logs.id) as event_logs_count").
  joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
  group('users.id').
  order('event_logs_count DESC')

您应该使用LEFT JOIN,因为您希望包含没有任何活动的用户。

如果你把它写成范围:

scope(:highest_completed_events, {
  select: 'users.*, COUNT(event_logs.id) as event_logs_count',
  joins: 'LEFT JOIN event_logs ON event_logs.user_id = users.id',
  group: 'users.id',
  order: 'event_logs_count DESC'
})

@users = User.highest_completed_events

要按特定状态过滤事件,只需使用where()即可。

@users = User.
  select("users.*, COUNT(event_logs.id) as event_logs_count").
  joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
  where('event_logs.status = ?', STATUS_COMPLETE).
  group('users.id').
  order('event_logs_count DESC')

顺便说一句,有时候你会遇到问题,ActiveRecord会在做select()这样的事情时剥离你的自定义@users.count语句。我通常做的是将这种东西嵌入自定义的from()语句中。

_from = User.
  select("users.*, COUNT(event_logs.id) as event_logs_count").
  joins('LEFT JOIN event_logs ON event_logs.user_id = users.id').
  group('users.id').
  order('event_logs_count DESC').to_sql

@users = User.from("(#{_from}) as users")

@users.count # will work

答案 1 :(得分:1)

尝试:

User.all.sort_by{|u| u.event_logs.select{|l| l.status_id = 2}.count}.reverse

还是'事件日志'?你的行不应该是has_many :event_logs吗?

BTW,我的解决方案效率不高,但与数据库无关。