Запрос «наибольшее число на группу» в Django 2.0?

В принципе, я хочу сделать это но с django 2.0.

Если я попробую:

Purchases.objects.filter(.....).annotate(my_max=Window( expression=Max('field_of_interest'), partition_by=F('customer') ) )

Я возвращаю все строки, но с добавлением свойства my_max к каждой записи.


person r_zelazny    schedule 02.07.2018    source источник
comment
Что делать, если у вас есть несколько строк с наибольшим значением в некоторых группах? Какой должен быть результат?   -  person Alexandr Tatarinov    schedule 02.07.2018


Ответы (1)


Если вы используете PostgreSQL:

Purchases.objects.filter(.....).order_by(
    'customer', '-field_of_interest'
).distinct('customer')

ОБНОВЛЕНИЕ: выражения окна не допускаются в фильтре, поэтому следующие методы не работают. Актуальное решение можно найти в этом ответе.

или с Window выражением

Purchases.objects.filter(.....).annotate(my_max=Window(
    expression=Max('field_of_interest'),
    partition_by=F('customer')
    )
).filter(my_max=F('field_of_interest'))

но последний может дать несколько строк для каждого покупателя, если у них одинаковые field_of_interest

Еще Window, с одной строкой для каждого покупателя

Purchases.objects.filter(.....).annotate(row_number=Window(
        expression=RowNumber(),
        partition_by=F('customer'),
        order_by=F('field_of_interest').desc()
        )
    ).filter(row_number=1)
person Alexandr Tatarinov    schedule 02.07.2018
comment
одно продолжение: когда я пытаюсь выполнить последний запрос, я получаю сообщение об ошибке: django.db.utils.NotSupportedError: Window is disallowed in the filter clause. Каждая строка имеет правильное свойство row_number, но сейчас я использую python, а не db, чтобы избавиться от всех записей с row_number ›1. Каким-либо образом обойти это? - person r_zelazny; 03.07.2018
comment
О, это для меня неожиданно. Я думаю, что если он не поддерживается, то, к сожалению, он не поддерживается .. - person Alexandr Tatarinov; 04.07.2018