Django эквивалент COUNT с GROUP BY
Я знаю, что в Django 1.1 есть несколько новых методов агрегации. Однако я не мог найти эквивалент следующего запроса:
SELECT player_type, COUNT(*) FROM players GROUP BY player_type;
Возможно ли это с помощью Django 1.1 Model Query API или я должен просто использовать простой SQL?
2 ответа
Если вы используете Django 1.1 beta (trunk):
Player.objects.values('player_type').order_by().annotate(Count('player_type'))
values('player_type')
- только для включенияplayer_type
поле вGROUP BY
пункт.order_by()
- для исключения возможно упорядочение по умолчанию, которое может привести к включению ненужных полей вSELECT
а такжеGROUP BY
,
Django 1.1 поддерживает такие методы агрегирования, как count. Вы можете найти полную документацию здесь.
Чтобы ответить на ваш вопрос, вы можете использовать что-то вроде:
from django.db.models import Count
q = Player.objects.annotate(Count('games'))
print q[0]
print q[0].games__count
Это потребует небольшой настройки в зависимости от вашей реальной модели.
Изменить: приведенный выше фрагмент генерирует агрегации для каждого объекта. Если вы хотите агрегировать в определенном поле в модели, вы можете использовать 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
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