我正在尝试使用先前行的子集的聚合来注释查询集。以下面的玩家在特定游戏中的得分示例表为例,last_2_average_score 列是特定玩家前两场游戏得分的滚动平均值。
+----------+-----------+---------+-------------------------+ | date | player | score | last_2_average_score | +----------+-----------+---------+-------------------------+ | 12/01/19 | 1 | 10 | None | | 12/02/19 | 1 | 9 | None | | 12/03/19 | 1 | 8 | 9.5 | | 12/04/19 | 1 | 7 | 8.5 | | 12/05/19 | 1 | 6 | 7.5 | +----------+-----------+---------+-------------------------+
In order to accomplish this, i wrote the following query, trying to annotate each "row" with the corresponding 2 game average for their score
ScoreModel.objects.annotate(
last_two_average_score=Subquery(
ScoreModel.objects.filter(
player=OuterRef("player"), date__lt=OuterRef("date")
)
.order_by("-date")[:2]
.annotate(Avg("score"))
.values("score__avg")[:1],
output_field=FloatField(),
)
)
但是,此查询不会输出正确的结果。事实上,结果就是每一条用
注释的记录{'last_two_average_score': None}
我尝试了多种不同的查询组合,但找不到正确的组合。如果您能提供任何建议,我们将不胜感激!
最佳答案
我没有首先尝试从 ORM 解决问题,而是转而首先尝试在原始 SQL 中实现查询。这立即让我想到了 WINDOW 函数的概念,当我在 Django 的 ORM 中查找时,很快就找到了。
https://docs.djangoproject.com/en/3.0/ref/models/expressions/#window-functions
对于这个感兴趣的人,生成的查询看起来像这样,这比我尝试使用子查询完成的要简单得多
ScoreModel.objects.annotate(
last_two_average=Window(
expression=Avg("score"),
partition_by=[F("player")],
order_by=[F("date").desc()],
frame=RowRange(start=-2, end=0),
)
)
关于python - Django 子查询先前记录的子集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59297483/