Files

111 lines
5.1 KiB
Python
Raw Permalink Normal View History

2026-09-21 19:14:15 +08:00
from sqlalchemy import func, case
from model.students import Student
from model.Score import Score
from model.employment import EmploymentBase,EmploymentOffer
from model.c_lass import Classinfo
def students_age(db,op:str,
age_value: int = None,
age_min: int = None,
age_max: int = None):
a=db.query(Student).filter(Student.is_deleted == 0)
if op == ">":
a=a.filter(Student.age > age_value)
elif op == "<":
a=a.filter(Student.age < age_value)
elif op == "=":
a=a.filter(Student.age == age_value)
elif op == ">=":
a=a.filter(Student.age >= age_value)
elif op == "<=":
a=a.filter(Student.age <= age_value)
elif op == "between":
if age_min is None or age_max is None:
raise ValueError("区间查询必须提供 age_min和age_max")
a=a.filter(Student.age.between(age_min, age_max))
else:
raise ValueError("请使用 >, <, =, >=, <=, between")
return a.all()
# 多维度班级统计**:统计每个班级的总人数,以及按性别(男、女)细分的人数分布。
def class_statistics(db):
a = (db.query(Student.class_id,func.count(Student.stu_id).label("total"),
func.sum(case((Student.gender == "男", 1), else_=0)).label("male"),
func.sum(case((Student.gender == "女", 1), else_=0)
).label("female"))
.filter(Student.is_deleted==0).group_by(Student.class_id).all())
list1 = []
for i in a:
list1.append({"class_id": i.class_id,"total": i.total,"male": i.male,"female": i.female})
return list1
# - 查询每次考试成绩都在输入分数线(如80分)以上的学生的编号、姓名和成绩。
def score_above(db,score_input):
result = []
for stu in db.query(Student).filter(Student.is_deleted == 0).all():
if stu.score and all(s.score >= score_input for s in stu.score):
for s in stu.score:
result.append((stu.stu_id, stu.stu_name, s.exam_id, s.score))
return result
# - 查询有输入指定次数(如两次)以上不及格的学生的姓名、班级和不及格成绩明细。
def score_fail(db, fail_times, fail_score=60):
result = []
for stu in db.query(Student).filter(Student.is_deleted == 0).all():
fails = [s for s in stu.score if s.score < fail_score]
if len(fails) >= fail_times:
for s in fails:
result.append((stu.stu_name, stu.class_id, s.exam_order, s.score))
return result
# - 统计每次考试每个班级的平均分,并支持按分数从高到低或从低到高动态排序。
def avg_scores(db, order="desc"):
avg = func.avg(Score.score).label("avg_score")
a = (db.query(Score.exam_id,Student.class_id,avg)
.join(Score.student).filter(Student.is_deleted == 0)
.group_by(Score.exam_id,Student.class_id))
a = a.order_by(avg.desc() if order == "desc" else avg.asc())
return a.all()
# - 统计就业薪资排名 Top N(动态输入 N)的学生的姓名、班级、就业时间和就业公司。
def top_salary(db, n):
a = (db.query(Student.stu_name,
Student.class_id,
EmploymentBase.job_time,
EmploymentBase.company_name,
EmploymentBase.salary).join(Student, EmploymentBase.stu_id == Student.stu_id)
.filter(EmploymentBase.is_deleted == 0, Student.is_deleted == 0)
.order_by(EmploymentBase.salary.desc()).offset(n-1).limit(1).first())
if not a:
return None
return {"name": a.stu_name,"class_id": a.class_id,"job_time": str(a.job_time) if a.job_time else None,
"company": a.company_name,"salary": a.salary}
# - 统计每个学生的就业时长(计算公式:offer下发时间 - 就业开放时间)。
def stu_every(db):
a = (db.query(Student.stu_id,
Student.stu_name,
EmploymentBase.employment_open_time,
EmploymentOffer.offer_time)
.join(EmploymentBase, EmploymentBase.stu_id == Student.stu_id)
.join(EmploymentOffer, EmploymentOffer.stu_id == Student.stu_id)
.filter(Student.is_deleted == 0,EmploymentBase.is_deleted == 0,
EmploymentOffer.is_deleted == 0).all())
return [{"stu_id": sid,"name": name,
"days": (offer_t - open_t).days if open_t and offer_t else None}
for sid, name, open_t, offer_t in a]
# - 统计每个班级的平均就业时长(仅统计进入就业阶段,即有就业开放时间的学生)。
def class_avg(db):
days = func.datediff(EmploymentOffer.offer_time,
EmploymentBase.employment_open_time).label("days")
a = (db.query(Student.class_id,
func.avg(days).label("avg_days"),
func.count().label("count"))
.join(EmploymentBase, EmploymentBase.stu_id == Student.stu_id)
.join(EmploymentOffer, EmploymentOffer.stu_id == Student.stu_id)
.filter(Student.is_deleted == 0,
EmploymentBase.is_deleted == 0,
EmploymentOffer.is_deleted == 0,
EmploymentBase.employment_open_time.isnot(None)).group_by(Student.class_id).all())
return [{"class_id": i.class_id, "avg_days": round(float(i.avg_days), 2)} for i in a]