【问题标题】:How to group by AND aggregate with Django如何使用 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 保持一致。

谢谢

【问题讨论】:

标签: django django-aggregation


【解决方案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')

【讨论】:

    猜你喜欢
    • 2019-10-12
    • 2020-11-09
    • 2020-11-16
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2019-01-31
    相关资源
    最近更新 更多