sticker0726

关于Django中关于ORM更多查询表达式,详情见中文文档

 聚合函数

在MySQL中我们知道聚合函数有下面这几种?

avg():返回指定组中的平均值

count():返回指定组中项目的总数量  

max():返回指定组中的数据最大值

min():返回指定组中的数据最小值

sum():返回指定组中的数据和

在Django中我们需要使用聚合函数就要放在aggregate函数里来计算。

aggregate(*args,**kwargs) :仅仅是一个聚合,并没有groupby 分组功能

通过对QuerySet进行计算,返回一个聚合值的字典。aggregate()中每一个参数都指定一个包含在字典中的返回值。即在查询集上生成聚合。

from django.db.models import Avg,Min,Sum,Max    #首先导入模块,注意大写

#从整个查询集生成统计值。比如,你想要计算所有在售书的平均价钱。Django的查询语法提供了一种方式描述所有图书的集合。

Book.objects.all().aggregate(Avg(\'price\'))      
# {\'price__avg\': 34.35}
 
# aggregate()子句的参数描述了我们想要计算的聚合值,在这个例子中,是Book模型中price字段的平均值
 
# aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。
如果你想要为聚合值指定一个名称,可以向聚合子句提供它:
Book.objects.aggregate(average_price=Avg(\'price\')) # {\'average_price\': 34.35} # 如果你也想知道所有图书价格的最大值和最小值,可以这样查询: Book.objects.aggregate(Avg(\'price\'), Max(\'price\'), Min(\'price\')) # {\'price__avg\': 34.35, \'price__max\': Decimal(\'81.20\'), \'price__min\': Decimal(\'12.99\')}

通过上面的介绍,我们可以知道,aggregate的逻辑比较简单,应用场景比较窄,如果你想要对数据进行分组(GROUP BY)后再聚合的操作,则需要使用annotate来实现。

分组聚合函数

annotate(*args,**kwargs) :   拥有分组和聚合的功能。它是和values合作实现分组聚合,values后边跟分组依据

 可以通过计算查询结果中每一个对象所关联的对象集合,从而得出总计值(也可以是平均值或总和),即为查询集的每一项生成聚合。最终得到的是特殊的Queryset,这个结果只包含value中的字段和聚合函数

以前我们用aggregate只能查询alex出的书总聚合     

 

查询各个作者出的书的总价格,这里就涉及到分组了,values后边跟分组条件是authors__name ,其实这里就像groupby authors_name 一样,用values进行分组然后再聚合

 

查询各个出版社最便宜的书价是多少,annotate可以起别名

annotate正向查询

 上面那个例子是正向查询,还是上面那个句子我们来反向查询一下也就是用出版社来查询,这时候values后面就不是跟的分组条件,这时候分组条件就变成了出版社的ID了:

publisher.objects.annotate(a=Max(book__price)).values("a)

我们可以看到反向查询也是只能得到分组条件和聚合函数的值,其他的值都不能得到,会报错

比如我们用反向查询获取各个出版社最便宜的书价是多少,书的名字

# publisher.objects.annotate(a=Max(book__price)).values("a,”book__name")

你会得到这个结果,因为:sqlmdoe = only_full_group_by

django.db.utils.InternalError: (1055, "Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 
\'text1.mytext.name\' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
")

这是orm

分类:

技术点:

相关文章: