Django ORM,通过查询求和列值
Posted
技术标签:
【中文标题】Django ORM,通过查询求和列值【英文标题】:Django ORM, Sum column values through query 【发布时间】:2021-12-20 13:08:42 【问题描述】:我有一个包含以下值的表:
user | amount | date |
---|---|---|
John | 10 | 2017-07-01 |
John | 20 | 2019-07-01 |
John | 30 | 2020-09-01 |
John | 40 | 2021-11-01 |
... | ... | ... |
Dan | -20 | 2019-02-01 |
Dan | -30 | 2020-04-01 |
Dan | -40 | 2021-06-01 |
函数的输入是一个日期范围,例如如下:
date_start = '2019-01-01'
date_end = '2021-11-07'
预期输出:
对于所有用户,对于这个日期范围内的每个日期,我想返回 amounts
的 sum
,从当前日期到所有以前的日期,如下所示:
user | amount | date |
---|---|---|
John | 30 (10+20)
|
2019-07-01 |
John | 60 (10+20+30)
|
2020-09-01 |
John | 100 (10+20+30+40)
|
2021-11-01 |
... | ... | ... |
Dan | -20 | 2019-02-01 |
Dan | -50 (-20-30)
|
2020-04-01 |
Dan | -90 (-20-30-40)
|
2021-06-01 |
我的努力
def get_sum_amount(self, date_start=None, date_end=None):
date_detail =
# Minimum date
if date_start:
date_detail['date__gt'] = date_start
# Maximum date
if date_end:
date_detail['date__lt'] = date_end
detail = Financial.objects.filter(Q(**date_detail)) \
.values('user') \
.annotate(sum_amount=Coalesce(Sum(F('amount')), Value(0)))
但没有结果。
更新
上例的函数输出为:
user | amount |
---|---|
John | 100 |
Dan | -90 |
【问题讨论】:
打印后能把输出贴在这里吗?? detail = Financial.objects.filter(Q(**date_detail)) \ .values('user') \ .annotate(sum_amount=Sum('amount'))) 我看到输出是正确的,对吗? @MohamedBeltagy 不,就像预期的输出一样,它应该返回,例如John
的另外两个日期,其值为 30 和 60。
这种情况下最好去shell手动写表达式查看输出
【参考方案1】:
您可以使用带有user
分区的Window
函数来计算每个用户的累积总和,按日期排序:
detail = Financial.objects.filter(**date_detail).annotate(
running_amount=Window(
expression=Sum('amount'),
partition_by=[F('user')],
order_by=F('date').asc(),
)
)
【讨论】:
以上是关于Django ORM,通过查询求和列值的主要内容,如果未能解决你的问题,请参考以下文章