Files
sss/student_system_final/dao/statistic_dao.py
T

167 lines
5.8 KiB
Python
Raw Normal View History

2026-09-21 22:13:04 +08:00
from typing import Optional
from sqlalchemy import and_, func, desc
from model.classes import Class
from model.student import Student
from model.student_score import Score
from model.work import Work
class Statistic:
def __init__(self,db):
self.db = db
def get_ages(self,age1:int,age2:Optional[int],condition:int):
stu = self.db.query(Student)
if not age2:
if condition == 1:
q=stu.filter(Student.age > age1).all()
elif condition == 2:
q=stu.filter(Student.age < age1).all()
elif condition == 3:
q=stu.filter(Student.age == age1).all()
else:
return f"输入错误,重新输入"
else:
if condition == 4:
q=stu.filter(and_(Student.age > age1, Student.age < age2)).all()
else:
return f"输入错误,重新输入"
return q
def get_class(self):
# 查询所有存在的班级cid(去重)
cid_list = self.db.query(Student.cid).distinct().all()
result = []
for row in cid_list:
cid = row.cid
# 当前班级全部学生
all_stu = self.db.query(Student).filter(Student.cid == cid).all()
total = len(all_stu)
if total == 0:
continue
# 男生
man_list = [s for s in all_stu if s.gender == "男"]
man_count = len(man_list)
# 女生
woman_list = [s for s in all_stu if s.gender == "女"]
woman_count = len(woman_list)
man_rate = man_count / total
woman_rate = woman_count / total
result.append({
"class_id": cid,
"total": total,
"male_count": man_count,
"male_rate": man_rate,
"female_count": woman_count,
"female_rate": woman_rate
})
return result
def get_grades(self, grades):
stu = self.db.query(Score).filter(Score.score > grades).distinct().all()
result = []
for st in stu:
result.append({
"sid": st.sid,
"score": st.score
})
return result
def get_bad_grades(self, number: int):
# 第一步:统计每个学生不及格(<60)的记录数量,筛选出不及格次数 >= number 的学生sid
sub_q = self.db.query(
Score.sid,
func.count(Score.score).label("bad_count")
).filter(Score.score < 60) \
.group_by(Score.sid) \
.having(func.count(Score.score) >= number) \
.subquery()
# 第二步:关联学生表+子查询,拿到满足条件学生的全部不及格成绩明细
bad_list = self.db.query(
Student.name,
Student.cid,
Score.score,
Score.exam_num
).join(sub_q, Student.sid == sub_q.c.sid) \
.join(Score, Student.sid == Score.sid) \
.filter(Score.score < 60) \
.all()
# 组装结果:按学生分组,一个学生一条,里面放成绩明细
result = {}
for name, cid, score, exam_num in bad_list:
key = (name, cid)
if key not in result:
result[key] = {
"name": name,
"cid": cid,
"bad_detail": [],
"bad_count": 0
}
result[key]["bad_detail"].append({"exam_num": exam_num, "score": score})
result[key]["bad_count"] += 1
return list(result.values())
def get_avg_grades(self, sort: int):
q = self.db.query(
Class.cid,
func.avg(Score.score).label("avg_score")
).join(Student,
Student.cid == Class.cid) \
.join(Score, Score.sid == Student.sid) \
.group_by(Class.cid)
data = q.all()
result = []
for item in data:
result.append({
"班级": item.cid,
"平均分": float(item.avg_score)
})
if sort == 1:
result.sort(key=lambda x: x["平均分"], reverse=True)
elif sort == 2:
result.sort(key=lambda x: x["平均分"], reverse=False)
else:
return {"code": 400, "msg": "输入错误,sort只能填1或2"}
return result
# #
def get_top(self,top):
stu=self.db.query(Student.name.label("student_name"),
Student.cid.label("class_id"),
Work.offer_time,
Work.company_name,
Work.salary).join(Student,Student.sid==Work.sid)\
.order_by(desc(Work.salary)).offset(top - 1).limit(1).first()
if not stu:
return f"错误排名"
name,cid,time,cname,salary = stu
return {"名字":name,"班级":cid,"就业时间":time,"公司名":cname,"薪水":salary}
def get_time(self):
result = []
stu=self.db.query(Work.sid,
Work.open_time,
Work.offer_time).all()
for item in stu:
time=item.offer_time-item.open_time
result.append({"学生id":item.sid,"就业时长":time})
return result
# def get_avg_time(self):
# result = []
# stu=Query(Class.id.label("class_id"),
# func.datediff(Student_employment.offer_time, Student_employment.open_time).join(Student_employment,Student_employment.sid==Student.sid)\
# .join(Student,Student.cid==Class.cid).group_by(Class.id).fillter().all()