python - Django 子查询先前记录的子集

标签 python django django-models django-orm

我正在尝试使用先前行的子集的聚合来注释查询集。以下面的玩家在特定游戏中的得分示例表为例,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/

相关文章:

Django haystack SearchQuerySet 到 QuerySet

django - 在 Django 的 inlineformset_factory 中选择外键元素的子集

python - 编写仅采用特定类型的方法的正确 python 方法是什么?

python - 修改正在运行的python程序

python - 无法在 Django 中导入设置

python - create_user() 缺少 1 个必需的位置参数 : 'username'

mysql - Django Mysql循环查询但得到相同的输出

django - ModelForm clean_xxxx() 适用于 CharField,不适用于 URLField。 Django 1.5

python - 使用 SqlAlchemy 插入 MySQL 时间戳列值

python - Keras:功能性 API 嵌入层的输入层应该是什么?