Django真的简单聚合(或分组)

时间:2012-12-03 22:54:41

标签: sql django group-by aggregation

想象一下,我只想知道Django的 auth app 中具有相同 first_name 的用户数量。 我知道在SQL中如何做到这一点非常简单:

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

我也知道如何在Django中获得所需的输出(例如,像浏览所有用户,获取他们的电子邮件并执行过滤器计算,例如)。

通过Django的ORM有没有更简单的方法来做到这一点?如果我使用外键聚合而不是使用其中一个表字段,我可以完成它。我很确定我错过了什么。

感谢。

3 个答案:

答案 0 :(得分:1)

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
    """
})

答案 1 :(得分:1)

几年前我在博客上发表了关于this very issue的文章。与其他答案相反,它在Django中完全可能,不需要原始SQL。

答案 2 :(得分:0)

请检查: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提及!