三个聚合的过程
您可以在 Case 上使用 Sum(..),例如:
from django.db.models import Case, F, IntegerField, Sum, Value, When
agg = SomeModel.objects.aggregate(
total=Sum('value'),
total_pos=Sum(Case(
When(value__gt=0, then=F('value')),
default=Value(0),
output_field=IntegerField()
)),
total_neg=Sum(Case(
When(value__lt=0, then=F('value')),
default=Value(0),
output_field=IntegerField(),
))
)
(SomeModel 是我们要为其计算聚合的模型,value 是字段(这里是 IntegerField,包含我们要汇总的值)。
When(..) 对象因此指定我们为value__gt=0(值大于零)或value__lt=0(值小于零)的行传递'value' 值。
这将产生一个包含三个键的字典,例如:
# sample output
agg == {'total': 12, 'total_pos': 14, 'total_neg': -2}
然后您可以获取如下值:
agg['total'] # 12
具有两个聚合的进程
由于我们知道agg['total'] == agg['total_pos'] + agg['total_neg'],我们只能计算一个元素,然后对字典进行后处理,例如:
from django.db.models import Case, F, IntegerField, Sum, Value, When
agg = SomeModel.objects.aggregate(
total=Sum('value'),
total_pos=Sum(Case(
When(value__gt=0, then=F('value')),
default=Value(0),
output_field=IntegerField()
))
)
agg['total_neg'] = agg['total'] - agg['total_pos']
这可能更有效,因为我们避免检查每一行额外的时间(尽管这取决于数据库如何进行索引等)。