我想按日期在模型中创建一个总和,然后在一个查询中添加一个滚动平均值……。这可能吗?
假设我有一张这样的桌子,叫做“销售”:
|---------------------|------------------|--------------|
| Date | Category | Value |
|---------------------|------------------|--------------|
| 2020-04-01 | 1 | 55.0 |
|---------------------|------------------|--------------|
| 2020-04-01 | 2 | 30.0 |
|---------------------|------------------|--------------|
| 2020-04-02 | 1 | 25.0 |
|---------------------|------------------|--------------|
| 2020-04-02 | 2 | 85.0 |
|---------------------|------------------|--------------|
| 2020-04-03 | 1 | 60.0 |
|---------------------|------------------|--------------|
| 2020-04-03 | 2 | 30.0 |
|---------------------|------------------|--------------|
我想按日期对其进行分组(“类别”列不重要)并添加日期值的总和。然后我想添加过去 7 天的滚动平均值。
我试过这个:
days = (
Sales.objects.values('date').annotate(sum_for_date=Sum('value'))
).annotate(
rolling_avg=Window(
expression=Avg('sum_for_date'),
frame=RowRange(start=-7,end=0),
order_by=F('date').asc(),
)
)
.order_by('date')
这会引发此错误:
django.core.exceptions.FieldError: Cannot compute Avg('sum_for_date'): 'sum_for_date' is an aggregate
有什么想法吗?
你得到的错误是因为你试图计算同一查询中聚合字段('sum_for_date')的平均值。这对于 Django 的 ORM 是不可能的。
一种可能的解决方法是使用子查询来计算每日总和,然后使用另一个查询来计算滚动平均值。这是使用您的销售模型的示例:
from django.db.models import Avg, Sum, F, Window
from django.db.models.functions import Lag
# Subquery to calculate daily sums
daily_sums = (
Sales.objects
.values('date')
.annotate(sum_for_date=Sum('value'))
)
# Query to calculate rolling average
rolling_avg = (
daily_sums
.annotate(
rolling_sum=Window(
expression=Sum('sum_for_date'),
frame=Window(
expression=Lag('sum_for_date', offset=6),
start=0,
),
),
rolling_count=Window(
expression=Sum(1),
frame=Window(
expression=Lag('date', offset=6),
start=0,
),
),
)
.annotate(
rolling_avg=F('rolling_sum') / F('rolling_count')
)
.order_by('date')
)
这首先使用子查询计算每日总和,然后使用窗口函数计算滚动平均值。 rolling_sum 窗口函数计算前 7 天的总和,rolling_count 窗口函数计算前 7 天的日期计数。最后,我们将 rolling_sum 除以 rolling_count 得到滚动平均值。
请注意,此方法使用 Window 函数,这些函数仅在某些数据库(例如 PostgreSQL)中可用。如果您使用不同的数据库,您可能需要使用不同的方法来计算滚动平均值。
有关
Window
的更多信息:https://docs.djangoproject.com/en/dev/ref/models/expressions/#window-functions