Django聚合函数与分组查询

一:聚合查询

1.聚合函数作用
copy
聚合查询通常情况下都是配合分组一起使用的
2.聚合函数查询关键字:
copy
aggregate
3.聚合函数
copy
Max : 最大值 Min : 最小值 Sum : 求合 Count : 计数 Avg : 平均值
4.聚合函数使用
copy
# 聚合函数查询 from app01 import models from django.db.models import Max,Min,Sum,Count,Avg # 1.所有书的平均价格 res = models.Book.objects.aggregate(Avg('price')) print(res)

image

copy
# 2.上述方法一致性使用 res = models.Book.objects.aggregate(Max('price'), Min('price'), Sum('price'), Count('pk'), Avg('price')) print(res)

image

二:分组查询

1.分组查询
copy
annotate()为调用的QuerySet中每一个对象都生成一个独立的统计值(统计方法用聚合函数,所有使用前要从django.db.models引入Avg,Max,Count,Sum(首字母大写))。
2.返回值
  • 分组后,用values取值,则返回值是QuerySet书籍类型里面为一个个字典
  • 分组后,用values_list取值,则返回值是QuerySet数据类型里面为一个个元组

MySQL中的limit相当于ORM中的QuerySet数据类型的切片。

3.分组查询关键字
copy
annotate() 里面放聚合函数
  • values 或者 values_list 放在 annotate 前面:values 或者 values_list 是声明以什么字段分组,annotate 执行分组。
  • values 或者 values_list 放在annotate后面: annotate 表示直接以当前表的pk执行分组,values 或者 values_list 表示查询哪些字段, 并且要将 annotate 里的聚合函数起别名,在 values 或者 values_list 里写其别名。
  • filter放在 annotate 前面:表示where条件
  • filter放在annotate后面:表示having
4.分组查询特点
copy
分组之后默认只能获取分组的依据 组内其他字段都无法直接获取 严格模式 ONLY_FULL_GROUP_BY
5总结:

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

三:分组使用

1.统计每一本书的作者个数
copy
from django.db.models import Max, Min, Sum, Count, Avg # res = models.Book.objects.annotate() 按照书分组 正向查询 按字段 authors__kp 分组省略 __kp 将前面数据拿过来 res = models.Book.objects.annotate(authors_num=Count('authors')).values('title', 'authors_num') print(res)

image

copy
models后面点什么 就按什么分组 author_num 是我们自己定义的字段 用来存储统计出来的每本书对应的作者个数
2.统计每个出版社卖的最便宜的书的价格
copy
出版社查询书 反向 小写 跨表查询 res = models.Publish.objects.annotate(min_price=Min('book__price')).values('name', 'min_price') print(res)

image

3.统计不止一个作者的图书
copy
1.先按照图书分组 2.过滤出不止一个作者的图书 # 按书籍分组 正向 字段 每一本书对应的作者个数 筛选出每一本书作者个数大于1的 res = models.Book.objects.annotate(author_num=Count('authors')).filter(author_num__gt=1).values('title','author_num','authors__name') print(res)

image

4.查询每个作者出的书的总价格
copy
res = models.Author.objects.annotate(sum_price=Sum('book__price')).values('name', 'sum_price') print(res)
posted @   AlexEvans  阅读(304)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
🚀