【问题标题】:Django Really Simple Aggregation (or Group By)Django 真正简单的聚合(或分组依据)
【发布时间】:2012-11-21 12:11:31
【问题描述】:

想象一下,我只想知道在 Django 的 auth 应用程序 中具有相同 first_name 的用户数量。 我知道如何在 SQL 中轻松做到这一点:

SELECT first_name, COUNT(1) as num_users 
  FROM auth_user 
  GROUP BY first_name
  ORDER BY num_users DESC;

而且我还知道如何在 Django 中获得所需的输出(例如,像遍历所有用户,获取他们的电子邮件并执行 filtercount) )。

难道没有更简单的方法可以通过 Django 的 ORM 执行此操作吗?如果我使用外键而不是表字段之一进行聚合,我可以完成它。我很确定我错过了什么。

谢谢。

【问题讨论】:

    标签: sql django group-by aggregation


    【解决方案1】:

    检查这个:https://docs.djangoproject.com/en/dev/topics/db/aggregation/

    from django.db.models import Count
    auth_user.objects.annotate(num_users=Count('first_name'))
    

    对于更复杂的查询,您可以使用普通 SQL,但请尽量避免使用它。

    UPD 代码已修复。感谢 Timmy O'Mahony 的提及!

    【讨论】:

    • 这只会计算并返回所有设置了 first_name 的用户。
    【解决方案2】:

    Django 的annotations 允许您将一些基本计算附加到查询集中的每个对象(或整个查询集中的聚合),但您不能过滤这些注释(即,在您的情况下,您只想计算那些共享的用户)你的名字)

    Django 还具有F() objects,它允许您在查询中使用字段值。理想情况下,您可以将这些与注释结合使用来过滤您要注释的对象,but that's not currently possible (there's a fix on the way)

    因此,一个简单的解决方案是手动执行注释:

    users = User.objects.all().extra(select={
        'same_name_count' : """
        SELECT COUNT(*)
        FROM auth_user
        WHERE auth_user.first_name = user.first_name
        """
    })
    

    【讨论】:

      【解决方案3】:

      几年前我在博客上写过this very issue。与其他答案相反,在 Django 中完全有可能,不需要原始 SQL。

      【讨论】:

      • 从来不知道这件事。非常有用。
      • 谢谢@daniel-roseman :) 就像你在博客中所说的那样,它有据可查,我已经阅读了很多次但没有明白:/ 我认为你是当你说“因为(可能是正确的)不希望用 SQL 来表达事物时,它并不那么容易找到”
      猜你喜欢
      • 2020-01-17
      • 1970-01-01
      • 2020-12-27
      • 1970-01-01
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      • 2016-05-01
      • 2015-12-13
      相关资源
      最近更新 更多