Rails:将nils排序到范围的末尾?

时间:2011-04-02 02:04:04

标签: sql ruby-on-rails ruby-on-rails-3 sorting rails-activerecord

所以,我的Photo模型中有以下范围:

scope :best, order(:average_rating.desc)

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

如何将nils排序到此范围的末尾?

5 个答案:

答案 0 :(得分:17)

我在游戏中有点迟了但这又刚刚出现,解决方案真的不那么困难。

便携式解决方案是使用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。例如,如果您将事物从1评级为5,则可以使用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的情况。

答案 1 :(得分:10)

试试这个:)

scope :best, order("average_rating DESC NULLS LAST")

答案 2 :(得分:2)

我知道这是一段时间以前但不会在一些

中发挥作用
order("ISNULL(average_rating) DESC")

答案 3 :(得分:2)

虽然coalesce SQL方法是great,但如果您的数据库不支持这个,那么这里应该支持所有数据库的方法:

order("-average_rating DESC")

这将订购您的记录并将NULL放到最后。

答案 4 :(得分:0)

好吧,我从来没有找到一种适用于DB驱动程序的方法,所以我只是强迫所有以前为零的记录的值为零。这解决了我,虽然它有点野蛮。当计时器用完时我会接受这个,因为它是我使用的解决方案,但如果有人重新考虑这个并希望将来提供一个替代答案,我将很乐意接受以后的不同答案。

相关问题