是否可以在Django ORM查询中计算相关表中字段的表达式(例如:减法)的聚合(例如:和)?
有关我正在尝试实现的完整示例,请参阅此工作SQL Fiddle。我将其分解为两个问题(other one here)。在这种情况下,我有一个代表一系列数字的模型Sequence
,以及一个代表此序列中“链接”的模型Part
:
Sequence Sequence Sequence Sequence ...
0 5 20 15 ...
|-- Part --|-- Part --|-- Part --|-- ...
因此,每个Part
代表 delta ,这是序列中两个值之间的差异。我有一组(非连续的)部分,想要计算这些增量的总和。像这样:
sum([p.after.value - p.before.value for p in Part.objects.filter(...)])
但是在一个查询中(原因是我想将它用作更复杂的子查询)。在SQL中很容易做到:
select sum(a.value - b.value)
from part p
join sequence a on p.after_id = a.id
join sequence b on p.before_id = b.id
where condition
group by p.other_field;
我不知道如何使用Django ORM来做到这一点。我可以为一个值做到这一点:
Part.objects.filter(condition).aggregate(Sum('before__value')).values()
但不是涉及多个值的表达式。使用F()
is not supported yet,所以我正在寻找另一种方法。我还查看了this question,它也是关于聚合中的表达式,但the accepted answer(使用extra
)不适用于我的案例AFAIK,因为我感兴趣的字段不是在同一张表中,但在相关的表中。
>>> Part.objects.filter(condition).extra(select={
... 'delta':'sum(after__value - before__value)'
... })
DatabaseError: no such column: after__value
这是一个SSCCE,如果有人想要试验它:Download或Browse。它与上面链接的SQL fiddle具有相同的模型和数据。
答案 0 :(得分:0)
现在1.8实施support for F
expressions in aggregate
,答案变得简单明了:
Part.objects.filter(condition).aggregate(sum=Sum(F('after__value')-F('before__value'))).values()