Подтвердить что ты не робот

Django эквивалент COUNT с GROUP BY

Я знаю, что Django 1.1 имеет несколько новых методов агрегирования. Однако я не мог вычислить эквивалент следующего запроса:

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

Возможно ли это с Django 1.1 Model Query API или я просто использую простой SQL?

4b9b3361

Ответ 1

Если вы используете бета-версию Django 1.1 (trunk):

Player.objects.values('player_type').order_by().annotate(Count('player_type'))
  • values('player_type') - для включения только поля player_type в предложение GROUP BY.
  • order_by() - для исключения возможного упорядочения по умолчанию, которое может вызвать включение ненужных полей в SELECT и GROUP BY.

Ответ 2

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