django计算mysql均值,django聚合:求和然后取平均值

Using django's ORM annotate() and/or aggregate(): I want to sum up based on one category field and then average over the category values per date. I tried to do it using two annotate() statements but got a FieldError.

I'm doing this:

queryset1 = self.data.values('date', 'category').annotate(sum_for_field=Sum('category'))

Which outputs a ValuesQuerySet object with things like (so a sum for each value of category):

[{'category': 'apples', 'date': '2015-10-12', sum_for_field=2000},

{'category': 'carrots', 'date': '2015-10-12', sum_for_field=5000},

{'category': 'apples', 'date': '2015-10-13', sum_for_field=3000},

{'category': 'carrots', 'date': '2015-10-13', sum_for_field=6000}, ...

]

I then want to average the sum_for_field field for each date to output something like:

[ {'date': '2015-10-12', avg_final: 3500},

{'date': '2015-10-13', avg_final: 4500}, ...

]

I tried doing this:

queryset2 = queryset1.values('date', 'sum_for_field')

result = queryset2.annotate(avg_final=Avg('sum_for_field'))

But I got this FieldError:

FieldError: FieldError: Cannot compute Avg('sum_for_field'): 'sum_for_field' is an aggregate

解决方案

Aggregate annotation by group from many aggregate annotations by group is generally a complicated question, but Avg from Sum is a special much easier case.

Expression Avg('sum_for_field') can be evaluated as Sum('sum_for_field') / Count('category', distinct=True) that can be evaluated by Aggregate() expressions. The Sum('sum_for_field') equals Sum('amount').

Solution: (Expected names: The model is Data that has fields date, category, amount.)

qs = Data.objects.values('date').annotate(

avg_final=Sum('amount') / Count('category', distinct=True)

)

(I'm convinced that very similar questions would be without any solution by current Django 1.11, even with Subquery class, without using a strange extra() method and without raw SQL)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值