Rails ActiveRecord - 通过匹配号码进行订单查询

Rails ActiveRecord - Order query by matching number

我有一个名为 Location 的模型。这个 table 有 2 个我想按以下顺序排序的字段:rating(整数)和 name(字符串)。

我想按名字的字母顺序排序,但如果评级是 5,我希望该评级排在第一位。如果评级是除 5 以外的任何其他评级,我希望它们在 5 之后按字母顺序公正地显示。

这可能与 SQL 有关吗?我知道我显然可以使用 Ruby 的 Array#sort 做到这一点,但我想将其作为查询来做到这一点。

是的,你可以用一点 SQL 来做到这一点。您需要在 ORDER BY:

中包含一个 case 表达式
case rating when 5 then 0 else 1 end

这大致相当于 Ruby 中的 rating == 5 ? 0 : 1,因此它会将所有评级为 5 的位置放在第一位,然后是其他位置。然后按 name:

排序
Location.order(Arel.sql('case rating when 5 then 0 else 1 end, name'))

当然,您可以将其隐藏在一个范围内,以便于阅读和理解。

您可以使用 window 函数 ROW_NUMBER 为每个排名分配一个“序列”值。然后为该“序列”应用带有附加谓词的 case 语句以满足您的限制。

select rank,name 
  from ( select rank, name 
              , row_number() over (partition by rank
                                       order by rank, name ) rn  
           from location
       ) l
 order by case when rank=5 and rn<=3 then 0 else 1 end   
        , name;