Django中如何对amount字段按trx不同条件分别求和后累加
Django多条件字段求和实现方案
原写法正确性判断
你提供的写法不正确。Django ORM的Sum聚合函数不支持直接链式调用.filter()传递过滤条件,该写法会触发语法错误,无法正常执行。
推荐实现方案
方案1:直接合并过滤条件(性能最优)
如果你只需要trx=2和trx=3的总和,不需要单独保留两类的求和结果,直接将过滤条件合并即可,仅需一次聚合计算:
from django.db.models import Sum, Q, F, ExtractMonth reportusage = (Invoices.objects .annotate(month=ExtractMonth('datetime')) .values('month') .annotate( total=Sum('amount', filter=Q(trx__in=[2,3])), product=F('tenant') ) .order_by() )
方案2:分开计算两类求和再合并(灵活性最高)
如果后续需要单独使用trx=2或trx=3的求和结果,可以分开聚合后再相加:
from django.db.models import Sum, Q, F, ExtractMonth reportusage = (Invoices.objects .annotate(month=ExtractMonth('datetime')) .values('month') .annotate( trx2_total=Sum('amount', filter=Q(trx=2)), trx3_total=Sum('amount', filter=Q(trx=3)), total=F('trx2_total') + F('trx3_total'), product=F('tenant') ) .order_by() )
以上两种方案仅支持Django 2.0及以上版本。
方案3:Case When条件聚合(兼容性最优)
如果使用的Django版本低于2.0,没有聚合函数filter参数支持,可以用条件表达式实现:
from django.db.models import Sum, Case, When, IntegerField, F, ExtractMonth reportusage = (Invoices.objects .annotate(month=ExtractMonth('datetime')) .values('month') .annotate( total=Sum( Case( When(trx=2, then='amount'), When(trx=3, then='amount'), default=0, output_field=IntegerField() ) ), product=F('tenant') ) .order_by() )
内容的提问来源于stack exchange,提问作者blinkbink
相关产品推荐
相关产品推荐

