Python--day69--ORM聚合查询和分组查询

聚合查询和分组查询

聚合

aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。web

键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。django

用到的内置函数:函数

from django.db.models import Avg, Sum, Max, Min, Count

示例:spa

>>> from django.db.models import Avg, Sum, Max, Min, Count
>>> models.Book.objects.all().aggregate(Avg("price")) {'price__avg': 13.233333}

若是你想要为聚合值指定一个名称,能够向聚合子句提供它。3d

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

若是你但愿生成不止一个聚合,你能够向aggregate()子句中添加另外一个参数。因此,若是你也想知道全部图书价格的最大值和最小值,能够这样查询:code

>>> models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price")) {'price__avg': 13.233333, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}

分组

咱们在这里先复习一下SQL语句的分组。orm

假设如今有一张公司职员表:blog

 

 咱们使用原生SQL语句,按照部分分组求平均工资:排序

select dept,AVG(salary) from employee group by dept;

ORM查询:ci

from django.db.models import Avg Employee.objects.values("dept").annotate(avg=Avg("salary").values(dept, "avg")

连表查询的分组:

 

SQL查询:

select dept.name,AVG(salary) from employee inner join dept on (employee.dept_id=dept.id) group by dept_id;

ORM查询:

from django.db.models import Avg models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")

更多示例:

示例1:统计每一本书的做者个数

复制代码
>>> book_list = models.Book.objects.all().annotate(author_num=Count("author")) >>> for obj in book_list: ... print(obj.author_num) ... 2 1 1
复制代码

示例2:统计出每一个出版社买的最便宜的书的价格

>>> publisher_list = models.Publisher.objects.annotate(min_price=Min("book__price")) >>> for obj in publisher_list: ... print(obj.min_price) ... 9.90 19.90

方法二:

>>> models.Book.objects.values("publisher__name").annotate(min_price=Min("price")) <QuerySet [{'publisher__name': '沙河出版社', 'min_price': Decimal('9.90')}, {'publisher__name': '人民出版社', 'min_price': Decimal('19.90')}]>

示例3:统计不止一个做者的图书

>>> models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1) <QuerySet [<Book: 番茄物语>]>

示例4:根据一本图书做者数量的多少对查询集 QuerySet进行排序

>>> models.Book.objects.annotate(author_num=Count("author")).order_by("author_num") <QuerySet [<Book: 香蕉物语>, <Book: 橘子物语>, <Book: 番茄物语>]>

示例5:查询各个做者出的书的总价格

>>> models.Author.objects.annotate(sum_price=Sum("book__price")).values("name", "sum_price") <QuerySet [{'name': '小精灵', 'sum_price': Decimal('9.90')}, {'name': '小仙女', 'sum_price': Decimal('29.80')}, {'name': '小魔女', 'sum_price': Decimal('9.90')}]>