Django与GROUP BY相当于COUNT

Imr*_*ran 31 python sql django django-queryset django-aggregation

我知道Django 1.1有一些新的聚合方法.但是我无法弄清楚以下查询的等价物:

SELECT player_type, COUNT(*) FROM players GROUP BY player_type;
Run Code Online (Sandbox Code Playgroud)

是否可以使用Django 1.1的Model Query API,还是应该使用纯SQL?

Ale*_*lev 61

如果您使用的是Django 1.1 beta(trunk):

Player.objects.values('player_type').order_by().annotate(Count('player_type'))
Run Code Online (Sandbox Code Playgroud)
  • values('player_type')- 仅包含player_type字段到GROUP BY子句.
  • order_by()- 排除可能导致不需要的字段包含在SELECT和中的默认排序GROUP BY.


Aym*_*ieh 15

Django 1.1确实支持像count这样的聚合方法.您可以在此处找到完整的文档.

要回答您的问题,您可以使用以下内容:

from django.db.models import Count
q = Player.objects.annotate(Count('games'))
print q[0]
print q[0].games__count
Run Code Online (Sandbox Code Playgroud)

这需要稍微调整,具体取决于您的实际型号.

编辑:上面的代码段基于每个对象生成聚合.如果要在模型中的特定字段上进行聚合,可以使用以下values方法:

from django.db.models import Count
q = Player.objects.values('playertype').annotate(Count('games')).order_by()
print q[0]
print q[0].games__count
Run Code Online (Sandbox Code Playgroud)

order_by()是必需的,因为默认排序的字段会自动选中,即使它们没有显式传递给它们values().此调用将order_by()清除任何排序并使查询按预期运行.

此外,如果要计算用于分组的字段(相当于COUNT(*)),可以使用:

from django.db.models import Count
q = Player.objects.values('playertype').annotate(Count('playertype')).order_by()
print q[0]
print q[0].playertype__count
Run Code Online (Sandbox Code Playgroud)