Django 09-1模型层 查询(分组聚合)

Posted yedada

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django 09-1模型层 查询(分组聚合)相关的知识,希望对你有一定的参考价值。

Django 查询(分组、聚合)

一、聚合查询

# 聚合函数的使用场景
    -- 单独使用:不分组,只查聚合结果
    -- 分组使用:按字段分组,可查分组字段与聚合结果

# 导入聚合函数
from django.db.models import Avg, Max, Min, Count, Sum

单独聚合查询:aggregate(*args,**kwargs)

# 语法:
aggregate(别名=聚合函数('字段'))

# 规则:
1.可以同时对多个字段进行聚合处理:aggregate(别名1=聚合函数1('字段1'), ..., 别名n=聚合函数n('字段n'))
3.是QuerySet对象方法
2.方法返回值返回值为dict类型

# 案例:所有书中最贵的书的价格
Book.objects.all().aggregate(high_price=Max('price'))

aggregate(*args, **kwargs)

# 计算所有图书的平均价格
 from django.db.models import Avg
 Book.objects.all().aggregate(Avg('price'))

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

Book.objects.aggregate(average_price=Avg('price'))

分组查询概念

Book: id  name  price  publish_date  publish
1. 聚合函数可以单独使用: 将整张表作为一个大的分组,查询字段只能是聚合结果
select max(price), group_concat(name) from book where id < 10;

2. 聚合函数在分组下使用
select publish_id, max(price) as high_price from book group by publish_id having max(price) > 50

分组聚合查询 annotate

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

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

查询的一句是聚合的结果,可以查询分组字段

# 语法:
values('分组字段').annotate(别名=聚合函数('字段')).filter(聚合字段别名条件).values('取分组字段', '取聚合字段别名')

# 规则:
1.values(...).annotate(...)为分组组合,values控制分组字段,annotate控制聚合字段
2.values可按多个字段分组values('分组字段1', ..., '分组字段n'),??如果省略代表按操作表的主键分组
3.可以同时对多个字段进行聚合处理annotate(别名1=聚合函数1('字段1'), ..., 别名n=聚合函数n('字段n'))
4.分组后的的filter代表having判断,只对聚合字段进行条件判断,可以省略(对非聚合字段或分组字段进行条件判断代表where判断)
5.取字段值values(...)省略默认取所有分组字段与聚合字段,也可以自主取个别分组字段及聚合字段(取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段)

# 案例:每个出版社出版的最贵的书的价格高于50元的出版社名与最高价格
Book.objects.all().values('publish__name').annotate(high_price=Max('price')).filter(high_price__gt=50).values('publish__name', 'high_price')
取字段的values中出现了非分组或非聚合字段,该字段自动成为分组字段
res = UserInfo.objects.values('province', 'city').annotate(high_age=Max('age')).values('city', 'high_age', 'name')
res = UserInfo.objects.values('province', 'city').annotate(high_age=Max('age')).filter(city__contains="济南").values('city', 'high_age')
print(res)


案例:每个出版社出版的最贵的书的价格高于50元的出版社名与最高价格
res = Book.objects.values('publish__name')    .annotate(high_price=Max('price'))    .filter(high_price__gt=50)    .values('publish__name', 'high_price')
print(res)

res = Publish.objects.values('name')    .annotate(high_price=Max('book__price'))    .filter(high_price__gt=50)    .values('name', 'high_price')
print(res)

以上是关于Django 09-1模型层 查询(分组聚合)的主要内容,如果未能解决你的问题,请参考以下文章

肆拾捌 --- 模型层下

Django基础五之django模型层多表操作

Django系列

如何使用 Django 进行分组和聚合

Django聚合函数与分组查询

Django学习第7篇:Django之ORM跨表操作(聚合查询,分组查询,F和Q查询等)