Django выбор лучших n записей на группу с помощью ORM - PullRequest
1 голос
/ 01 марта 2020

После этого вопроса я пытаюсь получить 10 лучших записей для каждого critera group_by, но Django возвращает эту ошибку:

from django.db.models import F, Window
from django.db.models.functions import RowNumber

Purchases.objects.annotate(row_number=Window(
        expression=RowNumber(),
        partition_by=F('customer'),
        order_by=F('field_of_interest').desc()
        )
    ).filter(row_number=10)
raise NotSupportedError(
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.

Когда я удаляю .des c (), сообщение об ошибке меняется на:

ValueError: order_by must be either an Expression or a sequence of expressions.

Я использую PostgreSql. Это ошибка или я ошибаюсь где-то в моем запросе?

1 Ответ

1 голос
/ 02 марта 2020

Мы можем выбрать топ n для каждой группы с помощью Подзапрос .

Во-первых, давайте получим топ n Покупок на клиента

top_n_purchases_per_customer = Purchases.objects.filter(
    customer=OuterRef('customer')
).order_by('-field_of_interest')[:10]

Далее мы можем выбрать Покупки с соответствующими идентификаторами из топ-10 на каждого клиента.

top_n_purchases = Purchases.objects.filter(
    id__in=Subquery(top_n_purchases_per_customer.values('id'))
)

В сгенерированном запросе используется коррелированный подзапрос, поэтому он может стать медленным. Обязательно используйте индекс для field_of_interest и customer (желательно объединенный индекс по обоим полям (см. index_together в Django документах))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...