作用域按计数排序

时间:2019-02-09 22:16:04

标签: ruby-on-rails sorting count scope conditional-statements

我有一个Category has_many的模型Pendencies。我想创建一个范围,该范围按active = true的倾向量对类别进行排序,而不排除active = false

到目前为止,我有:

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

这将根据未决数目进行排序,但是我想按具有active = true的未决进行排序。

另一种尝试是:

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

这将按具有pendencies.active = true的未决数目进行排序,但不包括pendencies.active = false

谢谢您的帮助。

3 个答案:

答案 0 :(得分: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;

即使代码会将其丢弃,我们也必须在SQL中输出ActivePendnecies,因为否则优化器将有权丢弃ORDER BY

答案 1 :(得分:1)

我猜您想按活动的待命数量进行排序,而不忽略没有活动的待命类别。

那将是这样的:

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

请注意,如果某个类别没有活动的未决要求,则计数将为null,并将被添加到列表的末尾。 可以添加一个类似的子查询,以根据未完成的总金额进行排序...

答案 2 :(得分:0)

目前,我开发了以下方法(它正在工作,但我认为这不是最好的方法):

require_once '../php-includes/connect.inc.php';
global $db;
$assess_id=$_POST['assess_id'];
$quest_ref=$_POST['quest_ref'];
$email=$_POST['email'];
$type=$_POST['type'];

if($type=="file"){
    $file=$_FILES["file"];
    $fileName=$file["name"][0];
    if(empty($fileName)){
        echo "No File Selected";
        return;
    }
    $fileType=$file["type"][0];
    $fileData=$file["tmp_name"][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}
}