[英]Order_by in sqlalchemy with outer join
我有以下sqlalchemy查询:
score = Scores.query.group_by(Scores.email).order_by(Scores.date).subquery()
students = db.session.query(Students, score.c.id).filter_by(archive=0).order_by(Students.exam_date).outerjoin(score, Students.email == score.c.email)
然后我用以下方法渲染事物:
return render_template('students.html', students=students.all())
现在,问题是我希望显示学生的最后分数,因为其中有许多对应于每个用户。 但是第一个似乎已返回。 我在第一个查询中尝试了一些排序和order_by,但没有成功。
我如何影响和选择“得分”中的最新结果,才能与“学生”中的相应行配对?
谢谢!
首先,您要确保子查询仅为特定学生选择行。 您可以使用correlate
方法来做到这一点:
score = db.session.query(Scores.id).order_by(Scores.date.desc()).correlate(Students)
仅此一项无济于事,因为您无法访问学生。 的想法correlate
是,如果你使用Students
在你的子查询,它不会将它添加到FROM
列表,而是依赖于外部查询提供它。 现在,您将要优化查询(如果需要,可以加入条件):
score = score.filter(Students.email == Scores.email)
这将产生一个子查询,每次仅返回单个学生的分数。 剩下的问题是,每个学生是否必须获得多个分数。 如果是这样,则需要对其进行限制(如果没有,则也不需要上面的order_by
部分):
score = score.limit(1)
现在,您已确保查询返回单个标量值。 由于您是在选择上下文中使用查询,因此需要将其转换为标量值:
students = db.session.query(Students, score.as_scalar()).filter_by(archive=0).order_by(Students.exam_date)
as_scalar
方法是一种告诉SQLAlchemy的方法,该方法返回单个行和一列 。 因为否则您将无法选择它。
注意 :如果您as_scalar
,我不确定100%是否需要该limit
。 尝试一下并到期。 如果每个学生只有一个分数,那么您完全不必担心这些东西。
关于此方法的一些提示: Query
实例本身就是可迭代的。 这意味着只要您不打印它或类似的东西,就可以像列表一样传递查询,唯一的例外是它只能在访问时(懒惰)运行,并且可以动态优化它,例如可以切片it: students[:10]
只会选择前10个学生(如果您在查询中执行此操作,它将以LIMIT
执行而不是切片列表,前者效率更高)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.