#28395 closed Cleanup/optimization (fixed)
first() adds id field to group by clause on aggregation queries
| Reported by: | John Gresty | Owned by: | Botond Béres |
|---|---|---|---|
| Component: | Documentation | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Botond Béres | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When evaluating an aggregation query, for example:
MyModel.objects.values('group').annotate(value=Sum('value'))
works as expected. However adding first() to the end will add the id field into the resulting queryset and as such the annotated value will be the value of the first row, instead of the sum of the group.
>>> MyModel.objects.create(value=10)
<MyModel: MyModel object>
>>> MyModel.objects.create(value=20)
<MyModel: MyModel object>
>>> MyModel.objects.values('group').annotate(value=Sum('value'))
<QuerySet [{'group': 0, 'value': 30}]>
>>> MyModel.objects.values('group').annotate(value=Sum('value')).first()
{'group': 0, 'value': 10}
Change History (5)
comment:1 by , 8 years ago
| Component: | Database layer (models, ORM) → Documentation |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
| Type: | Bug → Cleanup/optimization |
| Version: | 1.11 → master |
comment:2 by , 8 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | new → assigned |
comment:3 by , 8 years ago
| Has patch: | set |
|---|
I've added a small patch that links from the first() definition to the aggregation section which mentions interaction with default ordering
Note:
See TracTickets
for help on using tickets.
The
first()method requires an ordering to be specified else it would return non-deterministic results hence why it's usingorder_by('pk')when the queryset isn't ordered.This is a bit similar to #10574 except the implicit ordering is added by
first()and not_meta.orderingso I'd suggest we link to the aggregation section mentioning interaction with default ordering or adjust the documention to account for that.IMHO it would have been better for
first()to raise an exception when called on an unordered queryset instead of implicitly choosingpkbut in your case I assume you want to eitherorder_by('group')or'value'before callingfirst().