Files
student_system/dao/age_analysis.py
T

136 lines
5.2 KiB
Python
Raw Normal View History

2026-09-21 18:03:04 +08:00
from fastapi import HTTPException
from model.classinfo import ClassInfo
from model.employment import Employment
from model.score import Score
from model.student import Student
from sqlalchemy.orm import Session
from sqlalchemy import case, func, text, and_
def analysis_student_age(db: Session, min_age: int | None = None, max_age: int | None = None):
#按年龄区间(>=min 且 <=max)查询学生,区间可缺省。
if min_age is not None and min_age < 0:
raise HTTPException(status_code=400, detail="最小年龄不能小于0")
elif min_age is not None and max_age is not None and min_age > max_age:
raise HTTPException(status_code=400, detail="最小年龄不能大于最大年龄")
elif min_age is None and max_age is None :
data_age= db.query(Student).all()
elif min_age is not None and max_age is None:
data_age = db.query(Student).filter(Student.age >= min_age).all()
elif max_age is not None and min_age is None:
data_age = db.query(Student).filter(Student.age <= max_age).all()
elif min_age is not None and max_age is not None:
data_age = db.query(Student).filter(and_(Student.age >= min_age, Student.age <= max_age)).all()
return data_age
def analysis_class_gender(db: Session):
#每个班级总人数及男、女人数。
data= (db.query(
Student.class_id,
func.count(Student.id).label("total"),
func.sum(case((Student.gender == "男", 1), else_=0)).label("gender_male"),
func.sum(case((Student.gender == "女", 1), else_=0)).label("gender_female"),
).group_by(Student.class_id).all())
return data
def analysis_score_over(db: Session, score_over: float = 0):
#每次考试成绩都在分数线以上的学生的编号、姓名和成绩。
qualified_student_ids = (
db.query(Score.student_id)
.group_by(Score.student_id)
.having(func.min(Score.score) >= score_over)
)
data=(
db.query(Student.id, Student.name, Score.score)
.join(Score, Student.id == Score.student_id)
.filter(Student.id.in_(qualified_student_ids))
.all()
)
return data
def analysis_score_not_qualified(db: Session, not_qualified_count: int = 1):
#有指定次数以上不及格(<60)的学生的姓名、班级和不及格成绩明细。
not_qualified_students = (db.query(Score.student_id)
.filter(Score.score < 60)
.group_by(Score.student_id)
.having(func.count(Score.student_id) >= not_qualified_count))
data=(db.query(Student.id, Student.name, Student.class_id, Score.score)
.join(Score, Student.id == Score.student_id)
.filter(Student.id.in_(not_qualified_students), Score.score < 60).all())
return data
def analysis_avg_score_order(db: Session, sort_type: str = "asc"):
#每次考试每个班级的平均分,asc/desc 排序。
if sort_type not in ("asc", "desc"):
raise HTTPException(status_code=400, detail="sort 参数只能为 asc 或 desc")
avg_score = func.avg(Score.score).label("avg_score")
query = (
db.query(Score.exam_seq, ClassInfo.class_name, avg_score)
.join(Student, Score.student_id == Student.id)
.join(ClassInfo, Student.class_id == ClassInfo.id)
.group_by(Score.exam_seq, ClassInfo.class_name)
)
if sort_type == "asc":
data = query.order_by(avg_score.asc()).all()
else:
data = query.order_by(avg_score.desc()).all()
return data
def analysis_employment_salary_order(db: Session, n: int = 1):
#就业薪资排名 Top N 的学生姓名、班级、就业时间和就业公司
data=(db.query(
Student.name,
Student.class_id,
Employment.employment_open_time,
Employment.company_name,
Employment.salary)
.join(Employment, Employment.stu_id == Student.id)
.order_by(Employment.salary.desc()).limit(n).all())
return data
def analysis_student_employment_time(db: Session):
#每个学生的就业时长(offer下发时间 - 就业开放时间,单位秒)。
data=(
db.query(
Employment.stu_id,
func.timestampdiff(
text("SECOND"),
Employment.employment_open_time,
Employment.offer_time,
).label("time_diff"),
)
.filter(
Employment.employment_open_time.isnot(None),
Employment.offer_time.isnot(None),
)
.all()
)
return data
def avg_employment_time(db: Session):
#每个班级的平均就业时长(仅统计有就业开放时间的学生,单位秒)
return (
db.query(
Student.class_id,
func.avg(
func.timestampdiff(
text("SECOND"),
Employment.employment_open_time,
Employment.offer_time,
)
).label("time_diff"),
)
.join(Employment, Employment.stu_id == Student.id)
.filter(
Employment.employment_open_time.isnot(None),
Employment.offer_time.isnot(None),
)
.group_by(Student.class_id)
.all()
)