Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何执行组由。。。用Django ORM计算还是求和?_Python_Django_Group By_Django Orm - Fatal编程技术网

Python 如何执行组由。。。用Django ORM计算还是求和?

Python 如何执行组由。。。用Django ORM计算还是求和?,python,django,group-by,django-orm,Python,Django,Group By,Django Orm,开场白: from django.db.models import Count result = Books.objects.values('author') .order_by('author') .annotate(count=Count('author')) from django.db.models import Sum result = Books.objects.values(

开场白:

 from django.db.models import Count

 result = Books.objects.values('author')
                       .order_by('author')
                       .annotate(count=Count('author'))
 from django.db.models import Sum

  result = Books.objects.values('author')
                        .order_by('author')
                        .annotate(total_price=Sum('price'))
这是一个经常出现在SO中的问题:

我已经编写了一个关于SO文档的示例,但由于文档将于2017年8月8日关闭,我将遵循的建议,并将我的示例转换为一篇自我回复的帖子

当然,我也非常乐意看到任何不同的方法


问题:

 from django.db.models import Count

 result = Books.objects.values('author')
                       .order_by('author')
                       .annotate(count=Count('author'))
 from django.db.models import Sum

  result = Books.objects.values('author')
                        .order_by('author')
                        .annotate(total_price=Sum('price'))
假设模型:

class Books(models.Model):
    title  = models.CharField()
    author = models.CharField()
    price = models.FloatField()
如何使用Django ORM在该模型上执行以下查询:

  • 分组依据。。。计数

    SELECT author, COUNT(author) AS count
    FROM myapp_books GROUP BY author
    
  • 分组依据。。。总和

    SELECT author,  SUM (price) AS total_price
    FROM myapp_books GROUP BY author
    

我们可以通过。。。按…计数或分组。。。SUMDjango ORM上的SQL等价查询,使用
Django.db.models
Count
SUM
方法,分别使用以下方法:

  • 按…分组。。。计数:

     from django.db.models import Count
    
     result = Books.objects.values('author')
                           .order_by('author')
                           .annotate(count=Count('author'))
    
     from django.db.models import Sum
    
      result = Books.objects.values('author')
                            .order_by('author')
                            .annotate(total_price=Sum('price'))
    
    现在,结果包含一个带有两个键的字典:author和
    count

       author    | count
     ------------|-------
      OneAuthor  |   5
     OtherAuthor |   2
        ...      |  ...
    
  • 按…分组。。。总和:

     from django.db.models import Count
    
     result = Books.objects.values('author')
                           .order_by('author')
                           .annotate(count=Count('author'))
    
     from django.db.models import Sum
    
      result = Books.objects.values('author')
                            .order_by('author')
                            .annotate(total_price=Sum('price'))
    
    现在,结果包含一个字典,它有两列:
    author
    total\u price

       author    | total_price
     ------------|-------------
      OneAuthor  |    100.35
     OtherAuthor |     50.00
         ...     |      ...
    
更新日期:2021年4月13日


正如@dgw在评论中指出的,在模型使用元选项对行进行排序(例如)的情况下,子句对于聚合的成功至关重要

您还应该添加带有group by和“having”过滤器的联接表。对我来说,这是违反直觉的,因为在SQL中,通常从父项开始,而在django中,则从子项开始。@Henrietta鞅如果我正确理解您的意思,您可以在提取
值之前使用
过滤器
。您的意思是在注释之后再次使用过滤器,orm足够聪明,知道它需要做什么吗?以下是对我有用的东西:语句行。对象。过滤器(支付日期:'2019-10-31')。选择与之相关的('ae')。值('ae''opp''own')。注释(tots=Sum('amt'))。过滤器(tots''gt=0)关键键是选择与之相关的字段名和父字段名的双下划线。第二个过滤器确实变成了“有”。str([obj].query)确认了这一点。另一件方便的事。也许我们应该强调(…)的顺序部分。如果模型使用不同的列进行排序,省略
order\u by()
子句将导致聚合失败。