【问题标题】:Django selecting top n records per group using ORMDjango使用ORM选择每组前n条记录
【发布时间】:2020-06-14 03:39:06
【问题描述】:

question 之后,我试图获取每个 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)
raise NotSupportedError(
django.db.utils.NotSupportedError: Window is disallowed in the filter clause.

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

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

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

【问题讨论】:

标签: python django postgresql


【解决方案1】:

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2015-03-23
    • 1970-01-01
    • 1970-01-01
    • 2019-01-17
    • 2021-03-27
    • 2019-01-23
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多