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

Django结合PostgreSQL使用distinct(fields)+aggregate报错如何解决

问题原因

你遇到的报错是Django ORM的已知限制:目前不支持在指定了具体字段的distinct()查询后直接执行聚合操作,所以无法直接在distinct("metric")后拼接annotate(Sum)实现求和。

解决方案

方案1:子查询过滤后聚合(写法简洁易读)

先通过子查询拿到所有metric对应最新条目的主键,再过滤出这些条目后做求和,代码如下:

from django.db.models import Sum

# 子查询仅返回每个metric最新条目的id
latest_data_ids = Data.objects.order_by("metric", "-date").distinct("metric").values_list("id", flat=True)

# 对最新条目聚合求和
result = Data.objects.filter(id__in=latest_data_ids).aggregate(total_value=Sum("value"))["total_value"]

PostgreSQL会自动优化这类子查询,不会产生额外的性能开销,适合绝大多数场景。

方案2:窗口函数实现单查询聚合(适合复杂统计场景)

通过RowNumber窗口函数给每个metric分组内的条目按日期倒序编号,过滤出编号为1的最新条目后直接聚合,全程只执行一次SQL查询:

from django.db.models import Sum, Window, F
from django.db.models.functions import RowNumber

result = Data.objects.annotate(
    # 按metric分组,每组内按日期倒序编号
    row_num = Window(
        expression=RowNumber(),
        partition_by=[F("metric")],
        order_by=F("date").desc()
    )
).filter(row_num=1).aggregate(total_value=Sum("value"))["total_value"]

如果后续需要同时做其他分组统计逻辑,该方案的扩展性更好。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 15:42:01