【问题标题】:django aggregation: sum then averagedjango聚合:求和然后平均
【发布时间】:2016-04-26 23:22:05
【问题描述】:

使用 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

【问题讨论】:

标签: python django orm


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-29
      • 2016-01-30
      • 1970-01-01
      • 2015-03-29
      • 1970-01-01
      • 1970-01-01
      • 2014-09-07
      相关资源
      最近更新 更多