table of Contents
First, the aggregate query
Aggregation (using the aggregate function query): aggregate()
is QuerySet
a termination clause, meaning that it returns a dictionary that contains a number of key-value pairs.
The aggregate value is the name of the key identifier, the value is computed aggregate value. Name of the key is automatically generated out according to the name field and aggregate functions.
Used built-in functions:from django.db.models import Avg,Sum,MAx,Min,Count
Example:
form django.db.models import Avg,Sum,MAx,Min,Count
# 假设我们已经有书这张表了
# 查询所有的书的平均价格
models.Boook.objects.all().aggregate(Avg('prince'))
{'price__avg': xxxx}
If you want to specify a name for the aggregate values, it can provide to the aggregation clause.
models.Book.objects.aggregate(average_price=Avg('price'))
{'average_price': xxxx}
If you want to generate more than one aggregate, you can to aggregate()
add another parameter clause. So, if you want to know all the books of the maximum and minimum prices, it can be a query:
models.Book.objects.all().aggregate(Avg("price"), Max("price"), Min("price"))
{'price__avg': xxx, 'price__max': Decimal('19.90'), 'price__min': Decimal('9.90')}
Second, grouping query
First to review together what Native SQL statements grouped the
Suppose now that there is a company employee table:
We want to use native SQL statements, grouped according to sector averages wages:
select dept Avg(salary) from employee group by dept
ORM query:
from django.db.models import AVG
Employee.objects.values("dept").annotate(avg=Avg('salary')).values(dept,'dept_avg')
这里需要注意的是annotate分组依据就是他前面的值,
如果前面没有特点的字段,则默认按照ID分组,
这里有dept字段,所以按照dept字段分组
Even table query packet:
Native SQL statements to query
select dept.name,Avg(salary) from employee inner join dept on(employee.dept_id=dept.id) group by dept_id
ORM query:
from django.db.models import AVG
models.Dept.objects.annotate(avg=Avg("employee__salary")).values("name", "avg")
Example Collection
示例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")
to sum up
corresponding to a parameter value is inside the sql statement to find select display field,
filter which filters a parameter corresponding to or having the inside where
represents a group by itself annotate effect, find the packet based on the foregoing, the polymerization expression placed inside the display, followed by filter may be used to increase the restrictions, the final value to represent the packet field value you want to find