Django聚合仅计数True值
我正在使用聚合函数来计算一个布尔值列的数量。我想知道有多少个值是True。
这是我的DJANGO代码:
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'),
)
感谢Peter DeGlopper的建议,使用了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'),
)
4 个回答
0
这个对我有效:
from django.db.models import Avg, Sum, Count, Q
aggregated_values = queryset.aggregate(
avg_length=Avg('field_name'),
total_reserved=Count('field_name', filter=Q(field_name=True)),
total_not_reserved=Count('field_name', filter=Q(field_name=False))
)
6
另一种计算布尔值的方法是:
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,然后再把这些数字加起来就可以了。
32
这是针对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))))
更多信息请查看:
9
更新:
自从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)))
)
)
可以了解一下条件表达式类
旧答案。
看起来你想做的事情是一种“条件聚合”。目前,聚合
函数不支持像filter
或exclude
这样的查找方式,比如字段名小于(__lt)、字段名大于(__gt)等。
所以你可以试试这个:
以下是官网的描述:
为Django查询提供条件聚合,就像Excel中的著名SumIf和CountIf一样。