values()和annotate()组合成group by 时,必须values再前,annotate在后,顺序不同则不起效果

本文探讨了在数据库查询中如何使用values()和annotate()方法来分组并计算聚合数据。通过具体的例子说明了不同顺序使用这两个方法时,查询结果的不同表现形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


values()

Ordinarily, annotations are generated on a per-object basis - an annotatedQuerySet will return one result for each object in the originalQuerySet. However, when a values() clause is used to constrain thecolumns that are returned in the result set, the method for evaluatingannotations is slightly different. Instead of returning an annotated resultfor each result in the original QuerySet, the original results aregrouped according to the unique combinations of the fields specified in thevalues() clause. An annotation is then provided for each unique group;the annotation is computed over all members of the group.

For example, consider an author query that attempts to find out the averagerating of books written by each author:

>>> Author.objects.annotate(average_rating=Avg('book__rating'))

This will return one result for each author in the database, annotated withtheir average book rating.

However, the result will be slightly different if you use a values() clause:

>>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))

In this example, the authors will be grouped by name, so you will only getan annotated result for each unique author name. This means if you havetwo authors with the same name, their results will be merged into a singleresult in the output of the query; the average will be computed as theaverage over the books written by both authors.

Order of annotate() and values() clauses

As with the filter() clause, the order in which annotate() andvalues() clauses are applied to a query is significant. If thevalues() clause precedes the annotate(), the annotation will becomputed using the grouping described by the values() clause.

However, if the annotate() clause precedes the values() clause,the annotations will be generated over the entire query set. In this case,the values() clause only constrains the fields that are generated onoutput.

For example, if we reverse the order of the values() and annotate()clause from our previous example:

>>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')

This will now yield one unique result for each author; however, onlythe author’s name and the average_rating annotation will be returnedin the output data.

You should also note that average_rating has been explicitly includedin the list of values to be returned. This is required because of theordering of the values() and annotate() clause.

If the values() clause precedes the annotate() clause, any annotationswill be automatically added to the result set. However, if the values()clause is applied after the annotate() clause, you need to explicitlyinclude the aggregate column.





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值