聚合函数

Aggregate

  aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

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

 

  如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

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

总结:aggregateQuerySet 的一个终止子句, 返回一个包含一些键值对的字典, 因此不能再使用类似filter, order_by 等语法。

 

Annotate

  为查询集的每一项生成聚合, 生成汇总值的第二种方法,是为QuerySet中每一个对象都生成一个独立的汇总值。比如,如果你在检索一列图书,你可能想知道每一本书有多少作者参与。每本书和作者是多对多的关系。我们想要汇总QuerySet.中每本书里的这种关系。

逐个对象的汇总结果可以由annotate()子句生成。annotate()子句被指定之后,QuerySet中的每个对象都会被注上特定的值。

annotations的语法和aggregate()子句相同。annotate()的每个参数都描述了将要被计算的聚合。比如,给图书添加作者数量的annotate

# Build an annotated queryset
>>> from django.db.models import Count
>>> q = Book.objects.annotate(Count('authors'))
# Interrogate the first object in the queryset
>>> q[0]
<Book: The Definitive Guide to Django>
>>> q[0].authors__count
2
# Interrogate the second object in the queryset
>>> q[1]
<Book: Practical Django Projects>
>>> q[1].authors__count
1

  

  和使用 aggregate()一样,annotate的名称也根据聚合函数的名称和聚合字段的名称得到的。你可以在指定注解时,为默认名称提供一个别名:

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

  与 aggregate() 不同的是, annotate() 不是一个终止子句。annotate()子句的返回结果是一个查询集 (QuerySet);这个 QuerySet可以用任何QuerySet方法进行修改,包括 filter(), order_by(), 甚至是再次应用annotate()

 

聚合函数

注意

  在QuerySet 为空时,聚合函数函数将返回None例如,如果QuerySet 中没有记录,Sum 聚合函数将返回None 而不是0Count 是一个例外,如果QuerySet 为空,它将返回0

avg

  class Avg(expression, output_field=None, **extra)

  返回给定expression 的平均值,其中expression 必须为数值。

  • 默认的别名:<field>__avg
  • 返回类型:float

Count

  class Count(expression, distinct=False, **extra)

  返回与expression 相关的对象的个数。

  • 默认的别名:<field>__count
  • 返回类型:int

  有一个可选的参数:

  distinct

  如果distinct=True,Count 将只计算唯一的实例。它等同于COUNT(DISTINCT <field>) SQL 语句。默认值为False

Max

  class Max(expression, output_field=None, **extra)

  返回expression 的最大值。

  • 默认的别名:<field>__max
  • 返回类型:与输入字段的类型相同,如果提供则为 output_field 类型

Min

  class Min(expression, output_field=None, **extra)

  返回expression 的最小值。

  • 默认的别名:<field>__min
  • 返回的类型:与输入字段的类型相同,如果提供则为 output_field 类型

Sum

  class Sum(expression, output_field=None, **extra)

  计算expression 的所有值的和。

  • 默认的别名:<field>__sum
  • 返回类型:与输入的字段相同,如果提供则为output_field 的类型

 

应用实例

# Total number of books.
>>> Book.objects.count()
2452

# Total number of books with publisher=BaloneyPress
>>> Book.objects.filter(publisher__name='BaloneyPress').count()
73

# Average price across all books.
>>> from django.db.models import Avg
>>> Book.objects.aggregate(Avg('price'))
{'price__avg': 34.35}

# Max price across all books.
>>> from django.db.models import Max
>>> Book.objects.all().aggregate(Max('price'))
{'price__max': Decimal('81.20')}

# Cost per page
>>> Book.objects.all().aggregate(
...    price_per_page=Sum(F('price')/F('pages'), output_field=FloatField()))
{'price_per_page': 0.4470664529184653}

# All the following queries involve traversing the Book<->Publisher
# many-to-many relationship backward

# Each publisher, each with a count of books as a "num_books" attribute.
>>> from django.db.models import Count
>>> pubs = Publisher.objects.annotate(num_books=Count('book'))
>>> pubs
[<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
>>> pubs[0].num_books
73

# The top 5 publishers, in order by number of books.
>>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
>>> pubs[0].num_books
1323

 

 

。。。。。

posted @ 2017-05-25 17:37  Vincen_shen  阅读(325)  评论(0编辑  收藏  举报