Django 聚合仅计数真实值

问题描述 投票:0回答:4

我正在使用聚合来获取布尔值列的计数。我想要真实值的数量。

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'),
)
python django aggregate
4个回答
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)))
    )
)

了解条件表达式类

旧答案。

看来你想做的是某种“条件聚合”。目前

Aggregation
函数不支持类似
filter
exclude
的查找:fieldname__lt、fieldname__gt、...

所以你可以试试这个:

django-aggregate-if

摘自官方页面的描述。

Django 查询的条件聚合,就像 Excel 中著名的 SumIf 和 CountIf 一样。

您也可以先注释每个团队所需的价值,我的意思是为每个团队计算您感兴趣的领域中的

True
数量。然后做所有你想做的聚合


6
投票

count 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


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))
    )
© www.soinside.com 2019 - 2024. All rights reserved.