Rails: сортировать нули до конца области? - PullRequest
11 голосов
/ 02 апреля 2011

Итак, у меня есть следующая область действия в моей фотомодели:

scope :best, order(:average_rating.desc)

Единственная проблема в том, что рейтинги были добавлены в модель после факта, поэтому в рабочем приложении есть много записей, где average_rating равно нулю. Когда я называю эту область видимости, она возвращает сначала все нули - на самом деле все должно быть наоборот, нули должны быть последними (это фотографии, которые еще не оценены).

Как я могу отсортировать нули до конца этой области?

Ответы [ 5 ]

17 голосов
/ 21 января 2012

Я немного опоздал с игрой, но это только что появилось снова, и решение на самом деле не так уж сложно.

Переносимое решение состоит в использовании 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.

10 голосов
/ 02 апреля 2011

Попробуйте это:)

scope :best, order("average_rating DESC NULLS LAST")
2 голосов
/ 03 февраля 2014

, в то время как coalesce метод SQL равен отлично , если ваша база данных не поддерживает это, вот метод, который должен поддерживаться для всех баз данных:

order("-average_rating DESC")

Это упорядочит ваши записи и поставит NULL в конец.

2 голосов
/ 21 января 2012

Я знаю, что это было некоторое время назад, но не будет ли это работать через несколько

order("ISNULL(average_rating) DESC")
0 голосов
/ 03 апреля 2011

Ну, я никогда не находил подход, который бы работал с драйверами БД, поэтому я просто установил значение всех записей, которые ранее были равны нулю, равным нулю.Это решило это для меня, хотя это было немного грубо.Когда таймер истечет, я приму это, так как это решение я использовал, но если кто-нибудь еще вернется к нему и захочет предоставить альтернативный ответ в будущем, я буду рад принять другой ответ позже.

...