如何使用 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 进行分组和聚合的主要内容,如果未能解决你的问题,请参考以下文章

如何在 mongoDB 中使用聚合进行分组?

如何在数组的 mongodb 的子字段中进行聚合和分组?

django 中的聚合函数,分组函数,F 查询, Q查询

Django 09-1模型层 查询(分组聚合)

Django聚合函数与分组查询

Django---进阶6