对不好的标题表示歉意,因为除了我的 sql 技能之外,我不确定确切的问题是什么。
我有以下型号(为了清晰起见,进行了精简):
class Student (db.Model):
id = db.Column(db.Integer, primary_key=True)
good_behaviour_marks = db.Column(db.Integer)
tests = db.relationship('Test', backref='student', lazy='dynamic', cascade='all, delete-orphan')
@hybrid_property
def total_marks(self):
marks = self.good_behaviour_marks
for test in tests:
marks += tests.score
return marks
class Test (db.Model):
id = db.Column(db.Integer, primary_key=True)
subject = db.Column(db.String)
score = db.Column(db.Integer)
student_id = db.Column(db.Integer, db.ForeignKey('Student.id'))
一个学生可以参加多个科目的考试。我想编写一个查询来获取所有参加数学测试的学生的总分总和。
示例:
Student1 -> id:1 good_behaviour_marks:5 tests:[Math:10, Science:20] total_marks: 50
Student2 -> id:2 good_behaviour_marks:2 tests:[Science:15, English:20] total_marks:37
Student3 -> id:3 good_behaviour_marks:4 tests:[Math:10, Spanish:10] total_marks:24
查询应返回 -> 50 + 24 = 74,这是以数学为科目之一的学生的总分之和。
我正在使用flask-sqlalchemy,如果有帮助的话。我对 sql 查询的结构有一些了解:
select sum(total_marks)
from (
(
select
id, total_marks
from student
) a
leftjoin
(
select
student_id
from test
where subject=='Math'
) b
on (a.id == b.student_id)
group_by (id)
)
但我没有成功地将其转换为 sqlalchemy 查询。任何帮助将不胜感激。
您需要在学生和测试之间执行联接,过滤那些进行数学测试的学生,然后使用聚合函数对总分进行求和。像这样:
from sqlalchemy import func
# perform the join
students_with_math_tests = db.session.query(Student).join(
Test, Test.student_id == Student.id
).filter(
Test.subject == 'Math'
)
# calculate total marks
total_marks_sum = sum(student.total_marks for student in students_with_math_tests)
print(total_marks_sum)
这很简单,可能不适合大型数据集。 或者,您也可以直接在查询中处理总和:
result = db.session.query(
func.sum(Student.good_behaviour_marks + func.coalesce(func.sum(Test.score), 0))
).join(
Test, Test.student_id == Student.id
).filter(
Test.subject == 'Math'
).group_by(
Student.id
).all()
# since result will return a list of sums for each student, sum them up to get the total
total_marks_sum = sum(x[0] for x in result)
print(total_marks_sum)
这有点复杂,但应该更有效。希望这有帮助!