from sqlalchemy import func, desc from sqlalchemy.exc import SQLAlchemyError from model.epy_model import Employment from fastapi import HTTPException from model.stu_model import Student from model.sc_model import Scores # ① 超30岁学员 def get_stu_over_30(db): try: rows = db.query(Student).filter(Student.age>30,Student.is_deleted == 0).all() return [{'id': i.stu_id, 'name': i.stu_name} for i in rows] except SQLAlchemyError as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询超三十岁学员信息失败:{str(e)}') # ② 各班人数 + 男女比 def get_class_gender_count(db): try: rows = db.query( Student.class_id, Student.gender, func.count(1).label('num') ).group_by(Student.class_id, Student.gender).all() return [{'班级': r.class_id, '性别': r.gender, '人数':r.num } for r in rows] except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询各班人数与男女比例失败:{str(e)}') # ③ 每次考试都≥80分的学生 def get_stu_all_pass_80(db): try: rows = db.query( Scores.stu_id, Student.stu_name, func.min(Scores.score).label('min_score') ).join(Student, Student.stu_id == Scores.stu_id) \ .group_by(Scores.stu_id, Student.stu_name) \ .having(func.min(Scores.score) >= 80).all() t = ['stu_id', 'stu_name', 'min_score'] l = [dict(zip(t, row)) for row in rows] return l except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询成绩大于80的学生失败:{str(e)}') # ④ 两次以上不及格的学生 def get_stu_two_fail(db): try: rows = db.query( Student.stu_name, Student.class_id, ).join(Scores, Scores.stu_id == Student.stu_id) \ .filter(Scores.score < 60) \ .group_by(Scores.stu_id,Student.stu_name,Student.class_id) \ .having(func.count(Scores.id) >= 2).all() t = ['stu_name', 'class_id'] l = [dict(zip(t, row)) for row in rows] return l except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询两次不及格的学生失败:{str(e)}') # ⑤ 每次考试各班平均分(降序) def get_class_avg_sc(db): try: rows = db.query( Scores.exam_seq, Student.class_id, func.avg(Scores.score).label('avg_score') ).join(Student, Student.stu_id == Scores.stu_id) \ .group_by(Scores.exam_seq, Student.class_id) \ .order_by(desc('avg_score')).all() t = ['exam_seq', 'class_id','avg_score'] l = [dict(zip(t, row)) for row in rows] return l except Exception as e: db.rollback() raise HTTPException(status_code=400, detail=f'查询各班平均分失败:{str(e)}') # ⑥ 薪资前五名 def get_top5_salary(db): try: rows = db.query(Student.stu_name, Student.class_id,Employment.work_date,Employment.company,Employment.salary).join(Student, Student.stu_id == Employment.stu_id).order_by(Employment.salary.desc()).limit(5).all() t = ['stu_name','class_id','work_date','company','salary'] l = [dict(zip(t, row)) for row in rows] print(l) return {'code': 200, 'data': l} except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询薪资前五名失败失败:{str(e)}') # ⑦ 每个学生就业时长 def get_stu_duration(db): try: rows = db.query(Employment.stu_id,func.datediff(Employment.offer_date,Employment.open_date).label('offer_diff')).group_by(Employment.stu_id,Employment.offer_date,Employment.open_date).all() t = ['s_id', 'offer_diff'] l = [dict(zip(t, row)) for row in rows] return {'code': 200, 'data': l} except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询每个学生的就业时长失败:{str(e)}') # ⑧ 各班平均就业时长 def get_class_avg_duration(db): try: rows = db.query( Student.class_id, func.avg(func.datediff(Employment.offer_date, Employment.open_date)).label('avg_duration') ).join(Student, Student.stu_id == Employment.stu_id).filter( Employment.open_date.isnot(None) ).group_by(Student.class_id).all() t = ['class_id', 'avg_duration'] l = [dict(zip(t, row)) for row in rows] return l except Exception as e: db.rollback() raise HTTPException(status_code=400,detail=f'查询各班平均就业时长失败:{str(e)}')