8on*_*ne6 5 django orm aggregate-functions
假设我使用Django管理有关运动员的数据库:
class Player(models.Model):
name = models.CharField()
weight = models.DecimalField()
team = models.ForeignKey('Team')
class Team(models.Model):
name = models.CharField()
sport = models.ForeignKey('Sport')
class Sport(models.Model):
name = models.CharField()
Run Code Online (Sandbox Code Playgroud)
假设我想计算每个团队中球员的平均体重。我想我会这样做:
Team.objects.annotate(avg_weight=Avg(player__weight))
Run Code Online (Sandbox Code Playgroud)
但是,现在我要计算每个运动项目中球队权重的方差。有没有办法使用Django ORM做到这一点?extra()在QuerySet上使用该方法怎么样?任何建议深表感谢。
小智 0
你可以使用这样的查询:
class SumSubquery(Subquery):
template = "(SELECT SUM(`%(field)s`) From (%(subquery)s _sum))"
output_field = models.Floatfield()
def as_sql(self, compiler, connection, template=None, **extra_context):
connection.ops.check_expression_support(self)
template_params = {**self.extra, **extra_context}
template_params['subquery'], sql_params = self.queryset.query.get_compiler(connection=connection).as_sql()
template_params["field"] = list(self.queryset.query.annontation_select_mask)[0]
sql = template % template_params
return sql, sql_params
Team.objects.all().values("sport__name").annotate(variance=SumSubquery(Player.objects.filter(team__sport_id=OuterRef("sport_id")).annotate(sum_pow=ExpressionWrapper((Avg("team__players__weight") - F("weight"))**2,output_field=models.Floatfield())).values("sum_pow"))/(Count("players", output_field=models.FloatField())-1))
Run Code Online (Sandbox Code Playgroud)
并将相关名称添加到模型中,如下所示:
class Player(models.Model):
name = models.CharField()
weight = models.DecimalField()
team = models.ForeignKey('Team', related_name="players")
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1165 次 |
| 最近记录: |