10 Django aggregate query and query packet

First, the aggregate query

Aggregation (using the aggregate function query): aggregate()is QuerySeta 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:

img

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:

img

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

img

Guess you like

Origin www.cnblogs.com/xichenHome/p/11748010.html