初始化前后端学生管理系统项目
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
from sqlalchemy import func, case
|
||||
from sqlalchemy_fastapi_demo_1.model.students import Student
|
||||
from sqlalchemy_fastapi_demo_1.model.Score import Score
|
||||
from sqlalchemy_fastapi_demo_1.model.employment import EmploymentBase,EmploymentOffer
|
||||
from sqlalchemy_fastapi_demo_1.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.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]
|
||||
Reference in New Issue
Block a user