ORM分组与聚合查询

详解ORM的分组查询和聚合查询。

导入

from django.db.models import Avg,Min,Sum,Max
方法 描述
Avg 平均值
Min 最小值
Sum 求和
Max 最大值

聚合查询

aggregate(*args,**kwargs)

通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的返回值。即在查询集上生成聚合

比如,你想要计算所有在售书的平均价钱。
首先拿到所有的书的QuerySet对象,使用aggregate()函数直接拿到平均值。

>>> Book.objects.all().aggregate(Avg('price'))
{'price__avg': 34.35}

aggregate()子句的参数描述了我们想要计算的聚合值,在这个例子中,是Book模型中price字段的平均值。

aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。

当然我们也可以自己定义键名:

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

并且从上面的语法看,这个方法是可以接受多个方法参数的,也就是说,我们可以同时使用最大值,最小值,总和等方法作为参数:

>>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
{'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}

分类查询

语法

annotate(*args,**kwargs):

可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。

假设我们现在的需求是按照作者的名字分组:

>>> Book.objects.values('authors__name').annotate(Max('price'))
<QuerySet [{'authors__name': 'x1', 'price__max': Decimal('100.00')},
{'authors__name': 'x2', 'price__max': Decimal('100.00')},
{'authors__name': 'x3', 'price__max': Decimal('100.00')}]>

总结

  • 聚合是aggreate(),通过QuerySet 进行计算。做求值运算的时候使用。

  • 分组是annotate(),括号里是条件,遇到每什么什么的时候就要分组。


-------------本文结束感谢您的阅读-------------