10 Django 聚合查询和分组查询

一、聚合查询

聚合(利用聚合函数查询):aggregate()QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。

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

用到的内置函数:from django.db.models import Avg,Sum,MAx,Min,Count

示例:

form django.db.models import Avg,Sum,MAx,Min,Count
# 假设我们已经有书这张表了
# 查询所有的书的平均价格
models.Boook.objects.all().aggregate(Avg('prince'))
{'price__avg': xxxx}

如果你想要为聚合值指定一个名称,可以向聚合子句提供它。

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

如果你希望生成不止一个聚合,你可以向aggregate()子句中添加另一个参数。所以,如果你也想知道所有图书价格的最大值和最小值,可以这样查询:

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

二、分组查询

先来一起复习一下SQL原生语句的分组把

假设现在有一张公司职员表:

img

我们要使用SQL原生语句,按照部门分组求平均工资:

select dept Avg(salary) from employee group by dept

ORM查询:

from django.db.models import AVG
Employee.objects.values("dept").annotate(avg=Avg('salary')).values(dept,'dept_avg')
这里需要注意的是annotate分组依据就是他前面的值,
如果前面没有特点的字段,则默认按照ID分组,
这里有dept字段,所以按照dept字段分组

连表查询的分组:

img

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.annotate(num=count('author_id')).value('name',"num")
for obj in book_list:
    print(obj.author_num)
    
示例2:统计出每个出版社最便宜的书的价格
#方法一:
publisher_list = models.Publisher.objects.annotate(min_price=Min("book__price"))
for obj in publisher_list:
    print(obj.min_price) 
    
#方法二:
models.Book.objects.values("publisher__name").annotate(min_price=Min("price"))


示例3:统计不止一个作者的图书
book_obj=models.Book.objects.annotate(author_num=Count("author")).filter(author_num__gt=1)
print(obj)

示例4.查询各个作者出的书的总价格
res = models.Author.objects.annotate(price_sum = Sum("book__price")).values("price_sum")
print(res)

示例5:根据一本图书作者数量的多少对查询集 QuerySet进行排序
 models.Book.objects.annotate(author_num=Count("author")).order_by("author_num") 

总结

value里面的参数对应的是sql语句中的select要查找显示的字段,

filter里面的参数相当于where或者having里面的筛选条件

annotate本身表示group by的作用,前面找寻分组依据,内部放置显示可能用到的聚合运算式,后面跟filter来增加限制条件,最后的value来表示分组后想要查找的字段值

img

猜你喜欢

转载自www.cnblogs.com/xichenHome/p/11748010.html