Django模型查询总和为给定数字的前N行

Posted

技术标签:

【中文标题】Django模型查询总和为给定数字的前N行【英文标题】:Django model querying for first N rows that sum up to a given number 【发布时间】:2021-10-06 15:41:59 【问题描述】:

我在唱 Django 3.2

我有一个这样的模型:

class MyModel(models.Model):
    name = models.CharField(max_length=255)
    num_visits  = models.PositiveSmallNumber()
    created_at  = models.DateTimeField()

    class Meta:
        ordering = ['created_at']

我想选择访问次数的累积和 = 100的前N行(例如) 一种微不足道的(但可能是数据库密集型方式)是遍历表中的行(即查询集的元素)——但我不想这样做——原因应该很明显。

如何编写一个查询来获取访问总和为指定数字的前 N ​​行?

def get_rows_satisfying_visit_count(cumulative_sum_in_field=100):
    MyModel.objects.filter(/* what ? */)

【问题讨论】:

我已对问题进行了编辑,以更清楚地表明,我正在寻求检索的字段是具有 累积和 的最小行数。跨度> 【参考方案1】:

您可以对查询集使用切片运算符:

def get_rows_satisfying_visit_count(visits=100, rows=100):
    return MyModel.objects.filter(num_visits=number)[:rows]

编辑: 对于 Django >= 2.0 的更新问题,您可以使用 WindowSum 执行此操作:

MyModel.objects.annotate(
    cumulative_sum=Window(
        Sum('num_visits'),
        order_by=F('id').asc()
    )
).filter(cumulative_sum__lte=100)

这将获取累积总和小于或等于 100 的前几行。

【讨论】:

【参考方案2】:

你可以简单地使用

def get_rows_satisfying_visit_count(number=100):
    MyModel.objects.filter(num_visits=number)[:N]

查询集只会返回满足 num_visits 条件的前 N ​​个元素。 您可能认为它将返回所有满足条件的对象然后切片,但实际上,正在执行 LIMIT 数据库操作,因此它满足您的 DB 强度条件。 您可以查看https://docs.djangoproject.com/en/3.2/topics/db/queries/#limiting-querysets 了解更多信息。

【讨论】:

以上是关于Django模型查询总和为给定数字的前N行的主要内容,如果未能解决你的问题,请参考以下文章

Django 查询 - 如何按日期过滤总和?

Django:通过注释字段的总和订购查询集?

Django:分组然后通过查询计算列值的总和

在Django中计算模型属性的总和

使用 Django 查询计算过滤列值的总和时出错

用 Django ORM 中的前一个对象注释查询集