这可能为时已晚,但是我找到了解决方案(已在Django 1.11.1上进行了测试)。
问题是,.values('publisher')
提供分组所需的对的调用会删除.values()
参数中未包括的所有注释。
而且我们不能dbl_price
将param包含到 ,因为它将添加另一个GROUP BY
语句。
进行所有聚合的解决方案,首先需要带注释的字段,然后调用.values()
该聚合并将其包含到 param中(这不会添加GROUP BY
,因为它们是聚合)。然后,我们应该.annotate()
使用ANY表达式进行调用-这将使django addGROUP BY
语句使用query- 唯一的非聚合字段进行SQL查询。
Title.objects
.annotate(dbl_price=2*F('price'))
.annotate(sum_of_prices=Sum('dbl_price'))
.values('publisher', 'sum_of_prices')
.annotate(titles_count=Count('id'))
这种方法的唯一缺点- 如果除了带有带注释字段的聚合之外不需要其他任何聚合,则无论如何都必须包括一些聚合。如果没有对.annotate()的最后调用(它应该至少包含一个表达式!),Django将不会添加GROUP BY
到SQL查询中。一种解决方法是创建字段的副本:
Title.objects
.annotate(dbl_price=2*F('price'))
.annotate(_sum_of_prices=Sum('dbl_price')) # note the underscore!
.values('publisher', '_sum_of_prices')
.annotate(sum_of_prices=F('_sum_of_prices')
另外,请提及,您应谨慎使用QuerySet排序。您最好.order_by()
不带任何参数来清除顺序,也可以随便呼叫GROUP BY
。如果结果查询包含任何其他字段的排序,则分组将是错误的。 https://docs.djangoproject.com/zh- CN/1.11/topics/db/aggregation/#interaction-with-default-ordering-or-order- by
另外,您可能希望从输出中删除该假批注,因此再次调用.values()。因此,最终代码如下所示:
Title.objects
.annotate(dbl_price=2*F('price'))
.annotate(_sum_of_prices=Sum('dbl_price'))
.values('publisher', '_sum_of_prices')
.annotate(sum_of_prices=F('_sum_of_prices'))
.values('publisher', 'sum_of_prices')
.order_by('publisher')