如何使用 Django 进行分组和聚合
Posted
技术标签:
【中文标题】如何使用 Django 进行分组和聚合【英文标题】:How to group by AND aggregate with Django 【发布时间】:2012-11-04 09:53:34 【问题描述】:我想通过 ORM 进行一个相当简单的查询,但无法弄清楚..
我有三个模型:
位置(地点)、属性(地点可能具有的属性)和评分(还包含分数字段的 M2M 'through' 模型)
我想选择一些重要的属性并能够根据这些属性对我的位置进行排名 - 即所有选定属性的总分越高 = 越好。
我可以使用下面的 SQL 来得到我想要的:
select location_id, sum(score)
from locations_rating
where attribute_id in (1,2,3)
group by location_id order by sum desc;
返回
location_id | sum
-------------+-----
21 | 12
3 | 11
我能用 ORM 得到的最接近的是:
Rating.objects.filter(
attribute__in=attributes).annotate(
acount=Count('location')).aggregate(Sum('score'))
返回
'score__sum': 23
即所有的总和,不按位置分组。
有什么办法吗?我可以手动执行 SQL,但宁愿通过 ORM 保持一致。
谢谢
【问题讨论】:
docs.djangoproject.com/en/dev/topics/db/aggregation***.com/questions/629551/… How to query as GROUP BY in django?的可能重复 【参考方案1】:试试这个:
Rating.objects.filter(attribute__in=attributes) \
.values('location') \
.annotate(score = Sum('score')) \
.order_by('-score')
【讨论】:
hmmm - 注释不聚合 - 为什么会这样?aggregate
用于完整的结果集,annotate
用于单个(分组)行。
有谁知道如何解决'dict' object has no attribute '_meta'
这样的查询集?
嗨@Aamir,我有类似的问题,你能看看吗? link-here
返回类似["location": 53, "score": 100, "location": 54, "score": 104]
【参考方案2】:
你能试试这个吗?
Rating.objects.values('location_id').filter(attribute__in=attributes).annotate(sum_score=Sum('score')).order_by('-score')
【讨论】:
以上是关于如何使用 Django 进行分组和聚合的主要内容,如果未能解决你的问题,请参考以下文章