2009-05-08 28 views
26

Sé que Django 1.1 tiene algunos métodos de agregación nuevos. Sin embargo, yo no podía entender por equivalente de la siguiente consulta:Django equivalente de COUNT con GROUP BY

SELECT player_type, COUNT(*) FROM players GROUP BY player_type; 

¿Es posible con la API de consultas de modelo de Django 1.1 o debo utilizar SQL sin formato?

+0

Posible duplicado de [Django: cómo hacer SELECCIONAR COUNT (\ *) GROUP BY y ORDER BY] (http://stackoverflow.com/questions/19101665/django-how-to-do-select-count -group-by-and-order-by) –

Respuesta

55

Si está utilizando Django 1.1 beta (tronco):

Player.objects.values('player_type').order_by().annotate(Count('player_type')) 
  • values('player_type') - para inclusión solamente player_type campo en GROUP BY cláusula.
  • order_by() - para la posible exclusión de pedidos predeterminados que pueden causar la inclusión de campos no necesarios en SELECT y GROUP BY.
+13

+1 para .order_by() –

14

Django 1.1 admite métodos de agregación como count. Puede encontrar the full documentation here.

Para responder a su pregunta, se puede usar algo a lo largo de las líneas de:

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

Esto tendrá que ajustar ligeramente dependiendo del modelo real.

Editar: El fragmento de arriba genera agregaciones por objeto. Si desea que la agregación en un campo en particular en el modelo, se puede utilizar el values método:

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

order_by() es necesaria porque los campos que se encuentran en el orden predeterminado se seleccionan automáticamente, incluso si no se pasan explícitamente a values(). Esta llamada al order_by() borra cualquier orden y hace que la consulta se comporte como se esperaba.

Además, si se desea contar el campo que se utiliza para la agrupación (equivalente a COUNT(*)), puede utilizar:

from django.db.models import Count 
q = Player.objects.values('playertype').annotate(Count('playertype')).order_by() 
print q[0] 
print q[0].playertype__count 
+0

Esta llamada producirá una cláusula 'GROUP BY' incorrecta, con todos los campos del modelo incluidos. Pero el autor solo pidió una agrupación de campo. –

+0

Estaba tratando de dar un ejemplo general y señalar la documentación. Es por eso que dije que mi fragmento necesitaba ajustes. He agregado más ejemplos a mi respuesta ahora. Gracias por el comentario. :) –