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)
原文地址:https://www.cnblogs.com/Yedada/p/10492145.html
时间: 2024-11-09 12:51:35