【问题标题】:Django Subquery Subset of Previous Records以前记录的 Django 子查询子集
【发布时间】:2019-12-12 03:56:28
【问题描述】:

我正在尝试使用先前行的子集的聚合来注释查询集。以以下示例表为例,该表是某位球员在特定比赛中的得分,其中 last_2_average_score 列是特定球员前两场比赛得分的滚动平均值。

+---------+------------+---------+---------------- ---------+ |日期 |播放器 |分数 | last_2_average_score | +---------+------------+---------+---------------- ---------+ | 19 年 12 月 1 日 | 1 | 10 |无 | | 19 年 12 月 2 日 | 1 | 9 |无 | | 19 年 12 月 3 日 | 1 | 8 | 9.5 | | 19 年 12 月 4 日 | 1 | 7 | 8.5 | | 19 年 12 月 5 日 | 1 | 6 | 7.5 | +---------+------------+---------+---------------- ---------+

为了实现这一点,我编写了以下查询,尝试用相应的 2 场比赛平均得分来注释每个“行”

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}

我尝试了多种不同的查询组合,但找不到正确的组合。您能提供的任何建议将不胜感激!

【问题讨论】:

    标签: python django django-models django-orm


    【解决方案1】:

    我没有先尝试从 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),
        )
    )
    

    【讨论】:

      猜你喜欢
      • 2015-02-13
      • 1970-01-01
      • 2018-08-17
      • 1970-01-01
      • 2018-11-18
      • 2018-12-20
      • 2012-03-29
      • 1970-01-01
      • 2014-09-01
      相关资源
      最近更新 更多