You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Django ORM计算日期分组的累计求和?

按日期分组并计算当日数量与累计总数

我尝试基于日期对数据进行group_by()分组,同时需要计算当日的count以及截至当日的累计总数。

当前输出

[
    {
        "dates": "2022-11-07",
        "count": 1
    },
    {
        "dates": "2022-11-08",
        "count": 3
    },
    {
        "dates": "2022-11-09",
        "count": 33
    }
]

期望输出

[
    {
        "dates": "2022-11-07",
        "count": 1,
        "cumulative_count": 1
     },
    {
        "dates": "2022-11-08",
        "count": 3,
        "cumulative_count": 4
    },
    {
        "dates": "2022-11-09",
        "count": 33,
        "cumulative_count": 37
    }
]

现有查询语句

self.serializer_class.Meta.model.objects.all().annotate(dates=TruncDate("date__date")).values("dates").order_by("dates").annotate(count=Count("channel", distinct=True)).values("count", "dates")

解决方案

可以借助Django的Window函数结合Sum聚合,配合窗口范围设置来实现累计求和。修改后的查询语句如下:

from django.db.models import Count, F, Sum, Window
from django.db.models.functions import RowRange, TruncDate

self.serializer_class.Meta.model.objects.all()
    .annotate(dates=TruncDate("date__date"))
    .values("dates")
    .order_by("dates")
    .annotate(count=Count("channel", distinct=True))
    .annotate(
        cumulative_count=Window(
            Sum('count'),
            order_by=F('dates').asc(),
            frame=RowRange(start=None, end=0)
        )
    )
    .values("dates", "count", "cumulative_count")

说明

  • Window(Sum('count'), ...):为每一行计算count字段的累计总和
  • order_by=F('dates').asc():确保窗口按日期升序计算,保证累计顺序正确
  • frame=RowRange(start=None, end=0):定义窗口范围为从第一行到当前行,实现截至当日的累计求和

内容的提问来源于stack exchange,提问作者Hamza Shah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 12:31:01