在反向关系上具有多个 Sum 聚合的不同值
Distinct values with multiple Sum aggregations on reverse relation
根据 Django docs 将多个聚合与 annotate() 结合起来会产生错误的结果,因为使用的是连接而不是子查询。他们还注意到,Count
有一个独特的参数可能会有所帮助。
有没有类似Sum
的东西?在这个精简的示例中,我得到了错误的结果。生成的 amount
值对于大多数项目来说都太高了。
qs = Client.filter('project__date__year=2017').annotate(
isum=Sum('project__intoffer__amount', distinct=True),
esum=Sum('project__extoffer__amount', distinct=True)
)
distinct=True
参数没有任何区别。
简化models.py
:
class Client(models.Model):
title = models.CharField('Title', max_length=50)
class Project(models.Model):
title = models.CharField('Title', max_length=100)
client = models.ForeignKey('Client', verbose_name='Client')
date = models.DateField('Date', blank=True, null=True)
class IntOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
class ExtOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
你可以尝试使用django Subquery expression。在您的情况下,您的查询如下所示:
from django.db.models import Sum, OuterRef, Subquery
qs = Client.filter('project__date__year=2017').annotate(
isum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('intoffer__amount')).values('sum')[:1]),
esum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('extoffer__amount')).values('sum')[:1])
)
请注意,在大型表上它可能会很慢,在这种情况下最好使用 RawSQL。
根据 Django docs 将多个聚合与 annotate() 结合起来会产生错误的结果,因为使用的是连接而不是子查询。他们还注意到,Count
有一个独特的参数可能会有所帮助。
有没有类似Sum
的东西?在这个精简的示例中,我得到了错误的结果。生成的 amount
值对于大多数项目来说都太高了。
qs = Client.filter('project__date__year=2017').annotate(
isum=Sum('project__intoffer__amount', distinct=True),
esum=Sum('project__extoffer__amount', distinct=True)
)
distinct=True
参数没有任何区别。
简化models.py
:
class Client(models.Model):
title = models.CharField('Title', max_length=50)
class Project(models.Model):
title = models.CharField('Title', max_length=100)
client = models.ForeignKey('Client', verbose_name='Client')
date = models.DateField('Date', blank=True, null=True)
class IntOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
class ExtOffer(models.Model):
project = models.ForeignKey(Project, verbose_name='Project')
amount = models.DecimalField('Amount', max_digits=19, decimal_places=2)
你可以尝试使用django Subquery expression。在您的情况下,您的查询如下所示:
from django.db.models import Sum, OuterRef, Subquery
qs = Client.filter('project__date__year=2017').annotate(
isum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('intoffer__amount')).values('sum')[:1]),
esum=Subquery(Project.objects.filter(client=OuterRef('pk')).values('client_id').annotate(sum=Sum('extoffer__amount')).values('sum')[:1])
)
请注意,在大型表上它可能会很慢,在这种情况下最好使用 RawSQL。