django聚合:总和然后平均

时间:2016-01-20 22:01:12

标签: python django orm

使用django的ORM annotate()和/或aggregate():我想根据一个类别字段求和,然后对每个日期的类别值进行平均。我尝试使用两个annotate()语句但是得到了一个FieldError。

我这样做:

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

使用类似的东西输出一个ValuesQuerySet对象(所以类别的每个值的总和):

[{'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}, ...
]

然后我想平均每个日期的sum_for_field字段,输出如下内容:

[ {'date': '2015-10-12', avg_final: 3500},
{'date': '2015-10-13', avg_final: 4500}, ...
]

我试过这样做:

queryset2 = queryset1.values('date', 'sum_for_field')
result = queryset2.annotate(avg_final=Avg('sum_for_field'))

但是我得到了这个FieldError:

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

2 个答案:

答案 0 :(得分:2)

按组聚合注释按组聚合注释通常是一个复杂的问题,但Avg 中的 Sum是一个特殊的更容易情况下。

表达式Avg('sum_for_field')可以评估为Sum('sum_for_field') / Count('category', distinct=True),可由Aggregate() expressions进行评估。 Sum('sum_for_field')等于Sum('amount')

解决方案 :(预期名称:模型为Data,其中包含字段datecategoryamount。)

qs = Data.objects.values('date').annotate(
    avg_final=Sum('amount') / Count('category', distinct=True)
)

(我确信当前的Django 1.11没有任何解决方案,即使使用Subquery类,也没有使用奇怪的extra()方法且没有原始SQL,非常相似的问题)

答案 1 :(得分:0)

我没有深入研究,但我怀疑当你使用没有注释的values()时,sum_for_field值与共享相同date的值合并。我认为您需要在使用values()子句后立即评估注释。也许下面的内容可以解决您的问题:

result = queryset1.values('date').annotate(avg_final=Avg('sum_for_field'))