【问题标题】:Aggregation of an expression in Django query spanning multiple tables跨多个表的 Django 查询中的表达式聚合
【发布时间】:2013-03-05 10:08:04
【问题描述】:

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

有关我要实现的目标的完整示例,请参阅此工作 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,如果有人想尝试一下:DownloadBrowse。它与上面链接的SQL fiddle 具有相同的模型和数据。

【问题讨论】:

    标签: aggregate-functions django-orm table-relationships


    【解决方案1】:

    既然 1.8 实现了support for F expressions in aggregate,答案就变得直截了当:

    Part.objects.filter(condition).aggregate(sum=Sum(F('after__value')-F('before__value'))).values()
    

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 1970-01-01
      • 2012-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多