Django使用Subquery+OuterRef关联表Sum求和报子查询返回多行错误如何解决
错误原因
你当前的子查询逻辑会按照credit_used字段分组汇总,导致同一个用户关联的CreditOrder存在多个不同的credit_used值时,子查询会返回多行结果,不符合Django Subquery必须返回单个标量值的要求,最终抛出报错。
核心问题出在这行代码:.values('credit_used').annotate(credit_used_sum=Sum('credit_used'))
这里的values('credit_used')会将credit_used作为分组依据,相同值的记录才会汇总,最终生成多条分组汇总结果。
修复方案
调整子查询逻辑,去掉不必要的分组规则,直接对所有符合过滤条件的credit_used字段求和,确保子查询只返回单个值。需要先导入依赖的ORM函数:
from django.db.models import Sum, Subquery, OuterRef, DecimalField, Coalesce
修复后的查询代码如下:
def get_queryset(self, request): qs = super().get_queryset(request) qs = qs.filter(user_type='company') credits_used_subquery = Subquery( CreditOrder.objects.filter(credit__font__company__id=OuterRef('id')) .annotate(credit_used_sum=Sum('credit_used')) .values('credit_used_sum')[:1], # 取第一条确保只返回单行 output_field=DecimalField() ) qs = qs.annotate( # 用Coalesce处理无匹配订单的场景,默认返回0 _credits_used_sum=Coalesce(credits_used_subquery, 0) ) return qs
改动说明
- 移除了子查询中多余的
.values('credit_used')分组逻辑,直接对所有符合过滤条件的记录求和 - 在子查询末尾增加
[:1]限制,强制只返回单行结果,避免极端场景下的多行问题 - 新增
Coalesce函数处理用户没有关联CreditOrder的场景,默认返回0,避免字段值为null的异常
内容的提问来源于stack exchange,提问作者caiojhonny
相关产品推荐
相关产品推荐

