通过与条件Rails的计数范围订购

问题描述 投票:2回答:3

我有Categoryhas_many Pendencies的典范。我想创建一个由具有active = true不排除active = false的Pendencies量责令类别的作用域。

我至今是:

scope :order_by_pendencies, -> { left_joins(:pendencies).group(:id).order('COUNT(pendencies.id) DESC')}

这将通过pendencies数量订购它,但我想有active = true pendencies订购。

另一种尝试是:

scope :order_by_pendencies, -> { left_joins(:pendencies).group(:id).where('pendencies.active = ?', true).order('COUNT(pendencies.id) DESC')}

这将有pendencies.active = true pendencies数顺序,但会排除pendencies.active = false

谢谢您的帮助。

ruby-on-rails sorting count scope condition
3个回答
1
投票

我猜你想主动pendencies的量,而不会忽略不活跃pendencies类别进行排序。

这将是这样的:

scope :order_by_pendencies, -> { 
  active_count_q = Pendency.
    group(:category_id).
    where(active: true).
    select(:category_id, "COUNT(*) AS count")

  joins("LEFT JOIN (#{active_count_q.to_sql}) AS ac ON ac.category_id = id").
    order("ac.count DESC")
}

等效SQL查询:

SELECT *, ac.count 
FROM categories
LEFT JOIN (
    SELECT category_id, COUNT(*) AS count
    FROM pendencies
    GROUP BY category_id
    WHERE active = true
  ) AS ac ON ac.category_id = id
ORDER BY ac.count DESC

需要注意的是,如果有一个类别没有活跃pendencies,计数会为空,将被添加到列表的末尾。类似的子查询可以被添加到由pendencies总量还排序...


1
投票

C#的答案的要求:

method() {
    ....OrderBy((category) => category.Count(pendencies.Where((pendency) => pendency.Active))
}

或直SQL:

SELECT category.id, ..., ActivePendnecies
  FROM (SELECT category.id, ..., count(pendency) ActivePendnecies
          FROM category
          LEFT JOIN pendency ON category.id = pendency.id AND pendnecy.Active = 1
          GROUP BY category.id, ...) P
 ORDER BY ActivePendnecies;

我们要输出ActivePendnecies,即使代码将它扔了SQL,因为否则优化是其权利范围内抛出了ORDER BY


0
投票

现在,我制定了以下的(它的工作,但我相信,这是不是最好的方法):

  scope :order_by_pendencies, -> { scoped = Category.left_joins(:pendencies)
                                            .group(:id)
                                            .order('COUNT(pendencies.id) DESC')
                                            .where('pendencies.active = ?', true)
                                   all = Category.all
                                   (scoped + all).uniq}
© www.soinside.com 2019 - 2024. All rights reserved.