如何使用 Django 条件聚合仅对正值求和?

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

我有一张看起来像这样的桌子:

class MeasureValue(models.Model):
    cost_saving_10th = models.FloatField(null=True, blank=True)

我知道如何获得所有值的总和:

mvs.aggregate(Sum('cost_saving')).values()[0]

但是我如何获得所有值的总和呢?我想我需要一个条件聚合,但我不知道如何做到这一点。

python django
4个回答
13
投票

您可以使用 Django 条件表达式:

from django.db.models import Sum, F, Case, When


MeasureValue.objects.all().aggregate(
    positive_sum_cost_saving_10th=Sum(
        Case(
            When(cost_saving_10th__gt=0, then=F("warranty")),
            default=0,
        )
    )
)


{'positive_sum_cost_saving_10th': ... }

如果您不想过滤 QuerySet 以便通过某些其他字段进行聚合,这尤其有用。


6
投票

您可以在聚合之前过滤查询集,以使用

__gt
删除任何小于或等于 0 的值(
__gte
将包含 0,这只会为求和带来更多工作)

mvs.filter(cost_saving_10th__gt=0).aggregate(Sum('cost_saving_10th'))

注意:由于您正在过滤查询集,因此可能会丢失查询集结果中的条目。


2
投票

使用

filter
,然后使用
aggregate

>>> MeasureValue.objects.filter(cost_saving_10th__gte=0).aggregate(
...    sum=Sum('cost_saving_10th'))
{'cost_saving_10th__sum': ... }

这里有一些示例:Django 文档


1
投票

所以实际上,所有聚合函数都有一个

filter
参数,它接受一个
Q
对象。

因此,要仅对正值求和,您只需将其添加到代码中即可:

mvs.aggregate(Sum('cost_saving'), filter=Q(cost_saving__gt=0)).values()[0]
© www.soinside.com 2019 - 2024. All rights reserved.