一尘不染

Rails:将nils排序到作用域的末尾?

sql

因此,我的照片模型具有以下作用域:

scope :best, order(:average_rating.desc)

唯一的问题是,事实之后将评级添加到模型中,因此生产应用程序有很多记录,其中average_ratingnil为零。当我称这个范围时,它首先返回所有nil-
实际上应该相反,nil应该最后(它们是尚未评级的照片)。

如何将nil排序到此作用域的末尾?


阅读 214

收藏
2021-03-17

共1个答案

一尘不染

我玩游戏有点迟了,但这又来了,解决方案的确不是那么困难。

一种可移植的解决方案是使用CASE将NULL转换为结尾。如果您的评分为非阴性,则-1是一个不错的选择:

order('case when average_rating is null then -1 else average_rating end desc')

相反,使用COALESCE将在许多数据库中工作,并且比CASE少很多:

order('coalesce(average_rating, -1) desc')

如果您要进行ASC排序,则上述方法会将NULL放在开头。如果您最终希望使用它们,则可以使用比最高评分更高的值,而不是-1。例如,如果您将事物的评分从一分为五,则可以使用11代替NULL:

order('case when average_rating is null then 11 else average_rating end asc')
order('coalesce(average_rating, 11) asc')

大多数人会使用10,但有时您需要将其调高一些,所以我们将其调到11。

您不能真正依赖于数据库在开头或结尾放置NULL,因此即使您只是提醒自己自己已经处理了NULL情况,最好也要明确。

2021-03-17