美文网首页Django入门开发实战
Django模型层之多表操作(五)之聚合查询与分组查询

Django模型层之多表操作(五)之聚合查询与分组查询

作者: 乔治大叔 | 来源:发表于2019-01-25 16:58 被阅读27次

    聚合查询与分组查询

    聚合

    aggregate(*args, **kwargs)

    计算所有图书的平均价格

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

    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')}

    # 查询所有书籍的平均价格
        from django.db.models import Avg,Count,Max,Min
        ret=Book.objects.all().aggregate(Avg('price'))
        # {'price__avg': 202.896}
        # 可以改名字
        ret=Book.objects.all().aggregate(avg_price=Avg('price'))
        # 统计平均价格和最大价格
        ret=Book.objects.all().aggregate(avg_price=Avg('price'),max_price=Max('price'))
        # 统计最小价格
        ret = Book.objects.all().aggregate(avg_price=Avg('price'), min_price=Min('price'))
        # 统计个数和平均价格
        ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('price'))
        ret = Book.objects.all().aggregate(avg_price=Avg('price'), max_price=Max('price'),count=Count('nid'))
        print(ret)
    

    分组

    annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数)。

    总结 :跨表分组查询本质就是将关联表join成一张表,再按单表的思路进行分组查询。

    查询练习

    练习:统计每一本书作者个数

    from django.db.models import Avg, Max, Sum, Min, Max, Count
    book_list = models.Book.objects.all().annotate(author_num=Count("authors"))
    for book in book_list:
         print(book.name)
         print(book.author_num)
    book_list = models.Book.objects.all().annotate(author_num=Count("authors")).values('name','author_num')
    print(book_list)
    

    练习:统计每一个出版社的最便宜的书

    publishList=Publish.objects.annotate(MinPrice=Min("book__price"))
    for publish_obj in publishList:
    print(publish_obj.name,publish_obj.MinPrice)

    annotate的返回值是querySet,如果不想遍历对象,可以用上valuelist:

    queryResult= Publish.objects.annotate(MinPrice=Min("book__price")).values_list("name","MinPrice")
    print(queryResult)

    练习:统计每一本以py开头的书籍的作者个数:

    queryResult=Book.objects.filter(title__startswith="Py").annotate(num_authors=Count('authors'))

    练习:统计不止一个作者的图书:(作者数量大于一)

    ret=models.Book.objects.annotate(author_num=Count("authors")).filter(author_num__gt=1).values('name','author_num')
    print(ret)

    练习:根据一本图书作者数量的多少对查询集 QuerySet进行排序:

    Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')

    练习:查询各个作者出的书的总价格:

    ret=models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price")
    print(ret)

    练习:查询每个出版社的名称和书籍个数

    ret=models.Publish.objects.all().annotate(c=Count('book__name')).values('name','c')
    print(ret)

    相关文章

      网友评论

        本文标题:Django模型层之多表操作(五)之聚合查询与分组查询

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