【问题标题】:Aggregating query items with the same field value聚合具有相同字段值的查询项
【发布时间】:2020-03-07 09:25:00
【问题描述】:

我的一个查询集返回包含多个字段的项目列表:

<QuerySet [{'name': 'John', 'products': 4}, {'name': 'John', 'products': 6}, {'name': 'Sam', 'products': 7}, ...]>

我如何聚合这些数据以获取具有相同 name 字段的元素的 Sum()products 值的组合,以避免在查询集中出现重复,因此我会得到这样的结果:

<QuerySet [{'name': 'John', 'products': 10}, {'name': 'Sam', 'products': 7}, ...]>

我知道这应该使用 .annotate().aggregate() 查询来完成,但我不知道如何。

【问题讨论】:

    标签: django django-orm aggregation


    【解决方案1】:

    你需要的是annotate,你可以这样做:

    from django.db.models import Sum
    
    your_queryset = YourModel.objects.annotate(total_products=Sum('products')).values_list('name', 'total_products')
    

    您可以通过查看docs了解更多信息

    【讨论】:

      【解决方案2】:

      你可以构造这样的查询集:

      from django.db.models import Sum
      
      Model.objects.values('name').annotate(
          sum_products=Sum('products')
      ).order_by('name')

      .order_by(..) 是强制 Django 使用 GROUP BY 子句所必需的。

      【讨论】:

      • 我知道.values('name') 应该在.annotate() 子句之前,但究竟为什么呢?它是否告诉查询哪个字段用于分组?其背后的一般机制是什么?
      • @StanRedoute:完全正确。您需要指定将在选择部分中使用的值。 .annotate(..) 中的会自动添加。
      • 但是为什么查询中.values() 的顺序如此重要?我注意到,如果我在 .order_by() 之前将其移到末尾 - 查询返回的结果会略有不同(差异足以使其无法使用)。
      • @StanRedoute:因为这样您将在 GROUP BY 中考虑所有值。大多数 Django 操作都是“顺序敏感的”。您可以使用print(Model.objects.values(..).query) 打印 Django 将进行的查询。
      猜你喜欢
      • 1970-01-01
      • 2017-08-26
      • 2013-12-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多