Совокупность Django Count только True значения
Я использую агрегат, чтобы получить количество столбцов логических значений. Я хочу количество истинных значений.
КОД ДЖАНГО:
count = Model.objects.filter(id=pk).aggregate(bool_col=Count('my_bool_col')
Это возвращает количество всех строк.
SQL-запрос ДОЛЖЕН БЫТЬ:
SELECT count(CASE WHEN my_bool_col THEN 1 ELSE null END) FROM <table_name>
Вот мой фактический код:
stats = Team.objects.filter(id=team.id).aggregate(
goals=Sum('statistics__goals'),
assists=Sum('statistics__assists'),
min_penalty=Sum('statistics__minutes_of_penalty'),
balance=Sum('statistics__balance'),
gwg=Count('statistics__gwg'),
gk_goals_avg=Sum('statistics__gk_goals_avg'),
gk_shutout=Count('statistics__gk_shutout'),
points=Sum('statistics__points'),
)
Благодаря предложению Питера ДеГлоппера использовать django-aggregate-if
Вот решение:
from django.db.models import Sum
from django.db.models import Q
from aggregate_if import Count
stats = Team.objects.filter(id=team.id).aggregate(
goals=Sum('statistics__goals'),
assists=Sum('statistics__assists'),
balance=Sum('statistics__balance'),
min_penalty=Sum('statistics__minutes_of_penalty'),
gwg=Count('statistics__gwg', only=Q(statistics__gwg=True)),
gk_goals_avg=Sum('statistics__gk_goals_avg'),
gk_shutout=Count('statistics__gk_shutout', only=Q(statistics__gk_shutout=True)),
points=Sum('statistics__points'),
)
Ответы
Ответ 1
Обновление:
Начиная с Django 1.10 вы можете:
from django.db.models import Count, Case, When
query_set.aggregate(
bool_col=Count(
Case(When(my_bool_col=True, then=Value(1)))
)
)
Читайте о классах условных выражений
Старый ответ.
Похоже, что вы хотите сделать, это что-то вроде "условного агрегирования". В настоящее время функции Aggregation
не поддерживают поиск, например, filter
или exclude
: fieldname__lt, fieldname__gt,...
Таким образом, вы можете попробовать это:
Джанго-агрегированных если
Описание взято с официальной страницы.
Условные агрегаты для запросов Django, такие же, как известные SumIf и CountIf в Excel.
Вы также можете сначала аннотировать желаемое значение для каждой команды, я имею в виду подсчет для каждой команды суммы True
в интересующей вас области. А затем выполните все агрегацию, которую вы хотите.
Ответ 2
Обновлено для Django 1.10. Теперь вы можете выполнить условную агрегацию:
from django.db.models import Count, Case, When
query_set.aggregate(bool_col=Count(Case(When(my_bool_col=True, then=1))))
Дополнительная информация:
Ответ 3
Другое решение для графа Bool:
from django.db.models import Sum, IntegerField
from django.db.models.functions import Cast
Model.objects.filter(id=pk).annotate(bool_col=Sum(Cast('my_bool_col', IntegerField())))
Просто преобразуйте False
в 0 и True
в 1, а затем просто Sum