将状态分组并在 Rails 中调用 1 SQL 对这些状态进行排序

Group statuses together and sort within those status with 1 SQL call in Rails

我有一个 table profiles,它有三个没有 table 的字段:price, rating and status。到目前为止,我已经弄清楚如何按降序排列评级,然后在具有相同评级的记录中按升序排列价格:

Profile.all.order('rating DESC, price ASC')

反之亦然,在价格相同的记录中按价格升序排序然后评级降序排列:

Profile.all.order('price ASC, rating DESC')

但是,我有一个 statusinteger 类型,enum [:pending, :verified, :rejected]. I would like to make 1 SQL call that first groups the records of状态:已验证and every other status (已拒绝and待处理) after theverifiedgroup. Within theverified` 组,它将按评级 DESC 然后价格 ASC 对所有记录进行排序,反之亦然。在 "other" 组中,它会做同样的事情。

最终结果将是 2 个排序列表,其中所有 verified 条记录出现在 "other" 条记录之前。

我可以做 Profile.all.order('status DESC, rating DESC, price ASC'),并重新排列 verified 成为 enum 中最大的索引,但我希望 rejectedpending混在一起。

我只是认为查询会像这样:

Profile.joins("LEFT OUTER JOIN ( SELECT id, rating, price
                                 FROM profiles
                                 WHERE status = 'verified'
                               ) AS temp ON temp.id = profiles.id")
       .order("temp.rating DESC NULLS LAST, temp.price ASC NULLS LAST, profiles.rating DESC, profiles.price ASC")

解释:

  • 左外连接后,我们按 temp.rating DESC NULLS LAST 排序,这意味着我们按具有 status = verified 的个人资料评级排序,对于个人资料 status != verified,他们的 temp.ratingtemp.price 将是 NULL,这就是 NULLS LAST 在这里使用
  • 的原因
  • temp.price
  • 的想法相同

顺便说一句,您可以更改 WHERE status = 'verified' 以处理您的情况,因为例如

可能 status = 1