小编典典

django orm和postgresql的累积(运行)总和

python

是否可以使用Django的orm计算累积(运行)总和?考虑以下模型:

class AModel(models.Model):
    a_number = models.IntegerField()

带有一组数据的地方a_number = 1。这样我AModel在数据库中就拥有多个(> 1)个实例a_number=1。我希望能够返回以下内容:

AModel.objects.annotate(cumsum=??).values('id', 'cumsum').order_by('id')
>>> ({id: 1, cumsum: 1}, {id: 2, cumsum: 2}, ... {id: N, cumsum: N})

理想情况下,我希望能够限制/过滤累计金额。因此,在上述情况下,我想将结果限制为cumsum <= 2

我相信在postgresql中,可以使用窗口函数来实现累加和。这如何转换为ORM?


阅读 212

收藏
2021-01-20

共1个答案

小编典典

从DimaKudosh的答案中并基于我必须执行以下操作:我PARTITION BY在sql中删除了对的引用,并替换为ORDER BY结果。

AModel.objects.annotate(
    cumsum=Func(
        Sum('a_number'), 
        template='%(expressions)s OVER (ORDER BY %(order_by)s)', 
        order_by="id"
    ) 
).values('id', 'cumsum').order_by('id', 'cumsum')

这给出了以下sql:

SELECT "amodel"."id",
SUM("amodel"."a_number") 
OVER (ORDER BY id) AS "cumsum" 
FROM "amodel" 
GROUP BY "amodel"."id" 
ORDER BY "amodel"."id" ASC, "cumsum" ASC

Dima Kudosh的答案不是对结果求和,但以上结果可以。

2021-01-20