Select 每位运动员的最快时间

Select the fastest time for each athlete

我正在尝试生成每个运动员的最佳成绩列表,按时排序。

目前我只是在获得所有结果并按时订购后丢弃所有重复的结果。

我有以下两个模型:

class Athlete(models.Model):
    name = models.CharField(max_length=100)

class Result(models.Model):
    athlete = ForeignKey(Athlete, on_delete=models.CASCADE)
    time = models.DurationField()

说结果 table 看起来像这样:

athlete         time   
-------         ----
1               15.00
1               14.00
2               16.00
2               18.00
2               13.00
3               12.00

如何获取每个运动员的最快时间,然后按时间对列表进行排序? 像这样:

athlete         time   
-------         ----
3               12.00
2               13.00
1               14.00

您可以为此使用注释,例如:

from django.db.models import <b>Min</b>

Athlete.objects.annotate(
    <b>time=Min('result__time')</b>
).order_by(<b>'time'</b>)

从这个查询集产生的Athlete个对象将有一个额外的属性.time,其中相关的最小值time Result 对象。我们还使用 .order_by(..) 然后通过 time 注释对结果进行排序。

Django 将使用如下查询处理此问题:

SELECT athlete.*, <b>MIN(result.time) AS time</b>
FROM athlete
LEFT OUTER JOIN bar ON athlete.id = result.athlete_id
GROUP BY athlete.*
<b>ORDER BY time ASC</b>

如果 Athlete 没有相关的 Result,它的 time 将是 None

如果 Athlete 没有相关结果,而 Athlete 有相关结果,这取决于数据库,它会在哪里排序 NULL(在那些之前有值的,或者在有值的之后)。您可以通过在 F 表达式中使用 nulls_first or nulls_last [Django-doc] 指定如何使用 NULL 进行排序来解决该问题。例如:

from django.db.models import <b>F</b>, Min

Athlete.objects.annotate(
    time=Min('result__time')
).order_by(<b>F(</b>'time'<b>).asc(nulls_last=True)</b>)

这将在 QuerySet 结束时订购 Athletes 而没有任何结果。