2016-01-20 123 views
10

使用django的ORM批註()和/或聚合():我想基於一個類別字段進行總結,然後對每個日期的類別值進行平均。我試圖使用兩個annotate()語句來做到這一點,但得到了一個FieldError。django聚合:總和然後平均值

我這樣做:

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 
+1

您需要將'.annotate()'更改爲'.aggregate()'。有關更多信息,請參閱文檔:https://docs.djangoproject.com/en/1.9/topics/db/aggregation/ – jape

+0

@jape爲什麼不在一個答案中加入這個參考文獻[提供示例](https://docs.djangoproject.com/en/1.9/topics/db/aggregation/#aggregating-annotations)。 – tutuDajuju

+1

這個例子不是我想要的。 – user1387717

回答

0

我沒有做過深入瞭解,但我懷疑,當你使用values()沒有註解,sum_for_field值被合併那些份額相同date。我認爲您需要在使用values()條款後立即對註釋進行評估。也許類似下面將解決您的問題:從組許多總計註解

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

1

總結註釋按組通常是一個複雜的問題,但AvgSum是一個特殊的更容易情況。

表達式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)