Django使用ORM选择每组前n条记录

Meh*_*are 2 python django postgresql

按照这个问题,我试图获取每个 group_by 标准的前 10 条记录,但 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)
Run Code Online (Sandbox Code Playgroud)
raise NotSupportedError(
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.
Run Code Online (Sandbox Code Playgroud)

当我删除 .desc() 时,错误消息更改为:

ValueError: order_by must be either an Expression or a sequence of expressions.
Run Code Online (Sandbox Code Playgroud)

我正在使用 PostgreSql。这是一个错误还是我在查询中的某个地方错了?

Ale*_*nov 6

我们可以在Subquery 的帮助下选择每组前 n 个。

首先,让我们获得每个客户的前 n 次购买

top_n_purchases_per_customer = Purchases.objects.filter(
    customer=OuterRef('customer')
).order_by('-field_of_interest')[:10]
Run Code Online (Sandbox Code Playgroud)

接下来,我们可以从每个客户的前 10 个中选择具有匹配 ID 的购买。

top_n_purchases = Purchases.objects.filter(
    id__in=Subquery(top_n_purchases_per_customer.values('id'))
)
Run Code Online (Sandbox Code Playgroud)

生成的查询使用相关子查询,因此可能会变慢。确保对field_of_interest和使用索引customer(最好是两个字段的组合索引(参见Django 文档中的index_together))