2015-08-06 2 views
2

Я хочу иметь следующий порядок:Сортировать по NULL, то идентификатор по возрастанию

1 
2 
3 
NULL 
NULL 

В настоящее время у меня есть следующий запрос:

ItemInstance.objcts.filter(tv_series_id=item.pk).order_by('id') 

Это заказ по идентификатору ASC, но NULL придет в начало. Как бы я нажал NULL до конца, не выполняя второй запрос?

+0

Этот предыдущий вопрос может помочь: http://stackoverflow.com/questions/5993109/order-by-asc-with-nulls-at-the-bottom – Gene

+1

Так название намеренно вводит в заблуждение? – Strawberry

ответ

1

Вам нужно немного вычислить, как конвертировать NULL значения в нечто сопоставимое. Вот один из способов сделать это с помощью .annotate():

ItemInstance.objects.filter(tv_series_id=item.pk).annotate(
    null_ids=Count('id') 
).order_by('-null_ids', 'id') 

Кроме того, я думаю, вы также можете добиться, чтобы получить тот же результат с сырой SQL с помощью .extra():

ItemInstance.objects.filter(tv_series_id=item.pk).extra(
    'select': { 
     'is_null': 'CASE WHEN id IS NULL THEN 0 ELSE 1 END' 
    } 
).order_by('-is_null', 'id') 
0

Если вы используете Postgresql, вы можно установить индекс на этой колонке, чтобы положить NULLs первым или последним, например:

CREATE INDEX myindex ON mytable (mycolumn ASC NULLS LAST); 

Тогда база данных будет заботиться о нем.

Если индекс уже существует, вы можете его изменить .. вы также можете, если вам неудобно использовать прямой SQL, используйте pgadmin .. щелкните правой кнопкой мыши по индексу и выберите свойства, и вы найдете настройки в пределах ...

1

Вы можете использовать extra для определения настраиваемого поля, которое равно 0, когда id не имеет значения null и 1 в противном случае. Затем вы можете сначала отсортировать это поле, чтобы сначала получить ненулевые значения, а затем отсортировать по id.

ItemInstance.objects.filter(tv_series_id=item.pk).extra(
    select={'isnull': 'CASE WHEN id IS NULL THEN 1 ELSE 0 END'} 
).order_by('isnull', 'id') 
Смежные вопросы