美文网首页
Models and Databases 3.Aggregati

Models and Databases 3.Aggregati

作者: xncode | 来源:发表于2021-03-11 14:51 被阅读0次

    两种方式

    返回值

    Book.objects.all().aggregate(Avg('price'))
    Book.objects.aggregate(Avg('price'))
    Book.objects.aggregate(price__avg=Avg('price'))
    

    返回

    {'price__avg': 34.35}
    

    可同时产生多个值

    Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
    

    返回Queryset

    Book.objects.annotate(Count('authors'))
    Book.objects.annotate(authors__count=Count('authors'))
    

    返回的是Book的Queryset,其中会多一个authors__count字段代表值

    由于返回的是Queryset,所有可在结果上进一步操作

    注意:如果annotate多个,可能会有问题

    Book.objects.annotate(Count('authors'), Count('store'))
    

    使用的是join而不是subquery
    一般情况下只能使用两条语句来实现,但是对于count还是可以使用distinct语句

    Book.objects.annotate(Count('authors', distinct=True), Count('store', distinct=True))
    

    join

    可操作关系字段

    和其他查询语句的配合

    filter exclude

    注意和annotate同时使用的顺序问题,一般情况应该先过滤再使用annotate,否i则在有关系字段时可能发生错误,例如annotate时是按照全部数据进行处理,过滤时只取了一部分,但是已经产生了全部数据的结果

    可查看str(queryset.query)

    order by

    可使用annotate生成的字段进行排序

    values

    限制返回的列,计算聚合的方式也会不一样,不会再按全部的数据进行聚合,原始的数据会按values指定的字段进行group by,为每一个组进行聚合操作

    Author.objects.values('name').annotate(average_rating=Avg('book__rating'))
    

    Author会按照名字进行分组,得出他们各自的书的平均评价分数(注意名字的唯一性,否则会被合并在一起进行计算)

    注意排序或默认排序顺序,例如在Meta中的设置

    class Item(models.Model):
        class Meta:
            ordering = ["name"]
    

    即使在values中未出现但是也参与了分组,所以在使用时要去掉排序

    Item.objects.values("data").annotate(Count("id")).order_by()
    

    annotation and aggregate

    在使用了annotation后也可继续使用aggregate
    如果想计算每本书的平均作者数量,先annotate每个书本的作者数量,再aggregate作者

    Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors'))
    {'num_authors__avg': 1.66}
    

    这样会先拿到每个Book的作者数量,拿到一个中间表,在做aggregate的平均值,拿到作者数量的平均值

    相关文章

      网友评论

          本文标题:Models and Databases 3.Aggregati

          本文链接:https://www.haomeiwen.com/subject/mncalctx.html