Django - SELECT 具有相关子级最大 SUM 的行,GROUP BY 相关父级

Django - SELECT row with largest SUM of related child, GROUP BY related parent

我定义了三个模型,如下所示:

class Match(models.Model):
    id = models.IntegerField()

class Market(models.Model):
    match = models.ForeignKey(Match,on_delete=models.CASCADE)

class Issue(models.Model):
    market = models.ForeignKey(Market,related_name='issues',on_delete=models.CASCADE)
    volume = models.PositiveIntegerField()

结构如下:

每个Match有几个Market,每个Market有几个Issue


我想做的是: 对于每个匹配项,select 具有最大 Issue.volume

总和的市场

听起来很容易,但我想不通...

到目前为止我做了什么:

  1. 没有DISTINCT Match条件
Market.objects.annotate(total_volume=Sum('issues__volume')).order_by("-total_volume")

这按预期工作,但单个 Match 在我的 QuerySet 中多次出现。


  1. 首先尝试 DISTINCT Match 条件

然后我尝试添加一个DISTINCT(Match)。当我使用 Postgresql 时,我可以使用 distinct('match_id'):

Market.objects.annotate(total_volume=Sum('issues__volume')).order_by("match","-total_volume").distinct("match_id")

但它引发了以下错误: NotImplementedError: annotate() + distinct(fields) is not implemented.


  1. 第二次尝试 DISTINCT Match 条件

我使用以下方法实现了我的预期:

Market.objects.values('match_id').annotate(total_volume=Sum('issues__volume')).order_by("-total_volume")

但是,我想访问链接到特定 Market 的每个 Issue,这在这里是不可能的,因为使用了 values()


对于如何让它在尽可能少的请求下工作,您有什么想法吗?

感谢您的帮助!

好的,

它似乎通过诉诸子查询来工作:

l = Market.objects.filter(id=OuterRef('pk')).annotate(vol=Sum('issues__volume'))

Market.objects.annotate(total_volume=Subquery(l.values('vol')[:1])).order_by("match_id","-total_volume").distinct("match")

可以防止错误NotImplementedError: annotate() + distinct(fields) not implemented,但我不知道具体为什么!