1

是否可以从Django ORM 查询中的相关表中计算字段表达式(例如:减法)的聚合(例如:总和) ?

有关我要实现的目标的完整示例,请参阅此工作SQL Fiddle。我把它分解成两个问题(另一个在这里)。在这种情况下,我有一个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() 尚不支持使用,所以我正在寻找另一种方法。我还查看了这个问题,这也是关于聚合中的表达式,但接受的答案(使用extra)不适用于我的案例 AFAIK,因为我感兴趣的字段不在同一个表中,而是在一个相关的表中.

>>> Part.objects.filter(condition).extra(select={
...     'delta':'sum(after__value - before__value)'
... })

DatabaseError: no such column: after__value

这是一个 SSCCE,如果有人想尝试一下:下载浏览它具有与上面链接的SQL 小提琴相同的模型和数据。

4

1 回答 1

0

既然 1.8 实现了对F表达式的aggregate支持,答案就变得直截了当:

Part.objects.filter(condition).aggregate(sum=Sum(F('after__value')-F('before__value'))).values()
于 2015-06-16T08:29:40.463 回答