如何使用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
相关产品推荐
相关产品推荐

