通过ForeignKey外部引用对带有过滤器的子查询进行了汇总

弗雷德里克

我尝试从该SQL查询中编写等效的Django查询代码,但我遇到了麻烦。欢迎任何帮助。我收到了一场比赛id,从这个比赛中我想做一些统计:nb_race=给出比赛之前一匹马的比赛数量,best_chrono=给出比赛之前一匹马的最佳时间。

SELECT *, (SELECT count(run.id)
                FROM runner run
                INNER JOIN race
                ON run.race_id = race.id
                WHERE run.horse_id = r.horse_id
                AND race.datetime_start < rc.datetime_start 
                ) AS nb_race, 
          (SELECT min(run.chrono)
                FROM runner run
                INNER JOIN race
                ON run.race_id = race.id
                WHERE run.horse_id = r.horse_id
                AND race.datetime_start < rc.datetime_start 
                ) AS best_time
FROM runner r, race rc
WHERE r.race_id = rc.id
AND rc.id = 7890

Django模型:

class Horse(models.Model):
    id = AutoField(primary_key=True)
    name = models.CharField(max_length=255, blank=True, null=True, default=None)

class Race(models.Model):
    id = AutoField(primary_key=True)
    datetime_start = models.DateTimeField(blank=True, null=True, default=None)
    name = models.CharField(max_length=255, blank=True, null=True, default=None)

class Runner(models.Model):
    id = AutoField(primary_key=True)
    horse = models.ForeignKey(Horse, on_delete=models.PROTECT)
    race = models.ForeignKey(Race, on_delete=models.PROTECT)
    chrono = models.DecimalField(max_digits=10, decimal_places=2, blank=True, null=True, default=None)
催眠师

子查询表达式可用于将其他查询集编译为依赖于主查询集的子查询,并将它们作为一个SQL一起执行。

from django.db.models import OuterRef, Subquery, Count, Min, F

# prepare a repeated expression about previous runners, but don't execute it yet
prev_run = (
    Runner.objects
    .filter(
        horse=OuterRef('horse'),
        race__datetime_start__lt=OuterRef('race__datetime_start'))
    .values('horse')
)
queryset = (
    Runner.objects
    .values('id', 'horse_id', 'race_id', 'chrono', 'race__name', 'race__datetime_start')
    .annotate(
        nb_race=Subquery(prev_run.annotate(nb_race=Count('id')).values('nb_race')),
        best_time=Subquery(prev_run.annotate(best_time=Min('chrono')).values('best_time'))
    )
)

链接的文档中介绍了此处使用的一些技巧

  • 子查询的输出字段必须限制.values(...)为一个字段:仅汇总值
  • 子查询必须是一个查询集(被评估为惰性并组合在一起),而不是一个值(将被立即评估并失败)。因此.annotate()用于子查询(不是.aggregate())。这会增加一个GROUP BY race.horse_id,但不是问题WHERE race.horse_id = ...,因为在现代数据库后端中,SQL优化器最终也会忽略“ group by”。

它被编译为与示例中的SQL等效的查询。检查SQL:

>>> print(str(queryset.query))
SELECT ...,
  (SELECT COUNT(U0.id)
   FROM runner U0 INNER JOIN race U1 ON (U0.race_id = U1.id)
   WHERE (U0.horse_id = runner.horse_id AND U1.datetime_start < race.datetime_start)
   GROUP BY U0.horse_id
   ) AS nb_race,
   ...
FROM runner INNER JOIN race ON (runner.race_id = race.id)

边际差异是子查询使用一些内部别名,例如U0和U1。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

汇总的子查询注释a,由ForeignKey外部引用进行过滤

More_like_this带有过滤器的查询

Power Bi / Dax:汇总带有过滤器的表格

带有过滤器选项的Google图表MySQL查询百分比

弹性搜索 更像这个带有过滤器的查询是添加结果

带有过滤器的ElasticSearch function_score查询

ES 7 - 使用带有过滤器的匹配查询

PHP Elasticsearch,带有过滤器的布尔查询未获得任何结果

如何返回子数组的集合,并且最顶部的数组带有过滤器?

带有过滤器的Spring数据ElastiSearch聚合

带有过滤器的Pandas groupby()transform()max()

带有过滤器的Django ORM访问优化

带有过滤器的Django URL模板

.gitattributes使用带有过滤器的“ * text = auto”

带有过滤器的Django rest框架API

打开带有过滤器的报表

带有过滤器的 Rsyslog 加载模块

Python Web抓取带有过滤器的表

带有过滤器的Python BeautifulSoup抓取网站

带有过滤器的淘汰嵌套的foreach

分页的SQL查询具有过滤器

Dojo gridx过滤器:使用gridx过滤器时对服务器onkeypress进行了多次调用

带有过滤器的SVG图像-过滤器覆盖的区域大于图像

如何查询表以获取在链接中没有记录的记录以及带有过滤器的记录

g尾过滤器子页面通过ForeignKey

当执行参数化的N1QL查询时,Couchbase不使用带有过滤器的索引

返回页面时,带有过滤器搜索页面的Flutter不断从查询中添加相同的列表视图

使用带有RxJS的Angular 5可以看到带有过滤器的数组

ElasticSearch-带有过滤器的自定义分析器-未应用过滤器