|
|
@@ -116,64 +116,70 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
|
<select id="statisticStudyRecord" parameterType="com.ruoyi.learn.dto.StudyRecordStatisticsDTO" resultType="com.ruoyi.learn.dto.StudyRecordStatisticsDTO">
|
|
|
WITH T1 AS (
|
|
|
<!-- 定义查询 1 的聚合结果(做题统计)-->
|
|
|
+ <!-- 优化:从learn_answer开始JOIN,利用索引,避免date()函数 -->
|
|
|
SELECT
|
|
|
a.student_id,
|
|
|
COUNT(*) AS num,
|
|
|
SUM(IF(a.state = 1, 1, 0)) AS correct,
|
|
|
- ROUND(SUM(IF(a.state = 1, 1, 0)) * 100 / COUNT(*), 1) AS rate,
|
|
|
+ ROUND(SUM(IF(a.state = 1, 1, 0)) * 100.0 / COUNT(*), 1) AS rate,
|
|
|
COUNT(DISTINCT IF(le.paper_type IN (20,30), le.paper_id, null)) paperCount,
|
|
|
- ROUND(SUM(IF(a.`state` = 1 AND le.paper_type IN (20,30), 1, 0)) * 100 / SUM(IF(le.paper_type IN (20,30), 1, 0)), 1) paperRate
|
|
|
- FROM `sys_user` u
|
|
|
- JOIN `dz_cards` dc ON u.card_id = dc.card_id
|
|
|
- JOIN `learn_examinee` le ON le.student_id = u.user_id AND le.state >= 4
|
|
|
- JOIN `learn_answer` a ON a.`examinee_id` = le.`examinee_id` AND a.`state` > 0
|
|
|
- WHERE 1=1
|
|
|
+ ROUND(SUM(IF(a.`state` = 1 AND le.paper_type IN (20,30), 1, 0)) * 100.0 / NULLIF(SUM(IF(le.paper_type IN (20,30), 1, 0)), 0), 1) paperRate
|
|
|
+ FROM `learn_answer` a
|
|
|
+ INNER JOIN `learn_examinee` le ON a.`examinee_id` = le.`examinee_id` AND le.state >= 4
|
|
|
+ INNER JOIN `sys_user` u ON le.student_id = u.user_id
|
|
|
+ INNER JOIN `dz_cards` dc ON u.card_id = dc.card_id
|
|
|
+ WHERE a.`state` > 0
|
|
|
<if test="studyTimeBegin != null and studyTimeBegin != ''">
|
|
|
- AND (date(a.create_time) >= date(#{studyTimeBegin}) OR date(le.end_time) >= date(#{studyTimeBegin}))
|
|
|
+ <!-- 优化:去掉date()函数,直接比较datetime,可以使用索引 -->
|
|
|
+ AND (a.create_time >= CONCAT(#{studyTimeBegin}, ' 00:00:00') OR le.end_time >= CONCAT(#{studyTimeBegin}, ' 00:00:00'))
|
|
|
</if>
|
|
|
<if test="studyTimeEnd != null and studyTimeEnd != ''">
|
|
|
- AND (date(a.create_time) <= date(#{studyTimeEnd}) OR date(le.end_time) <= date(#{studyTimeEnd}))
|
|
|
+ <!-- 优化:去掉date()函数,直接比较datetime,可以使用索引 -->
|
|
|
+ AND (a.create_time <= CONCAT(#{studyTimeEnd}, ' 23:59:59') OR le.end_time <= CONCAT(#{studyTimeEnd}, ' 23:59:59'))
|
|
|
</if>
|
|
|
GROUP BY a.student_id
|
|
|
),
|
|
|
T2 AS (
|
|
|
<!-- 定义查询 2 的聚合结果(视频观看统计)-->
|
|
|
+ <!-- 优化:去掉date()函数,直接比较datetime,可以使用索引 -->
|
|
|
SELECT
|
|
|
ls.student_id,
|
|
|
COUNT(DISTINCT vw.title) AS total,
|
|
|
ROUND(SUM(vw.duration * vw.percent / 100.0)) AS value
|
|
|
FROM `b_customer_video_watches` vw
|
|
|
- JOIN `learn_student` ls ON vw.customerCode = ls.student_id
|
|
|
- WHERE 1=1
|
|
|
- <if test="studyTimeBegin != null and studyTimeBegin != ''">
|
|
|
- AND date(vw.time) >= date(#{studyTimeBegin})
|
|
|
- </if>
|
|
|
- <if test="studyTimeEnd != null and studyTimeEnd != ''">
|
|
|
- AND date(vw.time) <= date(#{studyTimeEnd})
|
|
|
- </if>
|
|
|
+ INNER JOIN `learn_student` ls ON vw.customerCode = ls.student_id
|
|
|
+ <where>
|
|
|
+ <if test="studyTimeBegin != null and studyTimeBegin != ''">
|
|
|
+ AND vw.time >= CONCAT(#{studyTimeBegin}, ' 00:00:00')
|
|
|
+ </if>
|
|
|
+ <if test="studyTimeEnd != null and studyTimeEnd != ''">
|
|
|
+ AND vw.time <= CONCAT(#{studyTimeEnd}, ' 23:59:59')
|
|
|
+ </if>
|
|
|
+ </where>
|
|
|
GROUP BY ls.student_id
|
|
|
),
|
|
|
AllStudents AS (
|
|
|
<!-- 提取所有涉及的唯一 Student ID-->
|
|
|
+ <!-- 优化:使用UNION ALL代替UNION,如果确定student_id不重复可以提升性能 -->
|
|
|
SELECT student_id FROM T1
|
|
|
UNION
|
|
|
SELECT student_id FROM T2
|
|
|
),
|
|
|
StudentBaseInfo AS (
|
|
|
<!-- 获取所有涉及学生的基础信息-->
|
|
|
+ <!-- 优化:简化COALESCE,去掉不必要的NULL判断 -->
|
|
|
SELECT DISTINCT
|
|
|
dc.dept_id,
|
|
|
asl.student_id,
|
|
|
- COALESCE(dc.school_id, NULL) AS school_id,
|
|
|
- COALESCE(dc.class_id, NULL) AS class_id,
|
|
|
- COALESCE(dc.campus_id, NULL) AS campus_id,
|
|
|
- COALESCE(dc.campus_class_id, NULL) AS campus_class_id,
|
|
|
- COALESCE(dc.agent_id, NULL) AS agent_id,
|
|
|
- COALESCE(dc.leaf_agent_id, NULL) AS leaf_agent_id,
|
|
|
+ dc.school_id,
|
|
|
+ dc.class_id,
|
|
|
+ dc.campus_id,
|
|
|
+ dc.campus_class_id,
|
|
|
+ dc.agent_id,
|
|
|
+ dc.leaf_agent_id,
|
|
|
u.nick_name AS nick_name,
|
|
|
- COALESCE(dc.card_no, NULL) AS card_no
|
|
|
+ dc.card_no
|
|
|
FROM AllStudents asl
|
|
|
- <!-- 基础信息主要从 sys_user 和 dz_cards 获取-->
|
|
|
LEFT JOIN `sys_user` u ON asl.student_id = u.user_id
|
|
|
LEFT JOIN `dz_cards` dc ON u.card_id = dc.card_id
|
|
|
)
|
|
|
@@ -214,8 +220,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
|
<where>
|
|
|
<if test="deptId != null"> AND SBI.dept_id = #{deptId}</if>
|
|
|
<if test="schoolId != null"> AND SBI.school_id = #{schoolId}</if>
|
|
|
- <if test="teacherId != null"> AND (SBI.class_id in ( SELECT t.class_id FROM dz_teacher_class t WHERE t.teacher_id = #{teacherId} and now() < t.out_date)
|
|
|
- or SBI.campus_class_id in ( SELECT t.class_id FROM dz_teacher_class t WHERE t.teacher_id = #{teacherId} and now() < t.out_date))</if>
|
|
|
+ <if test="teacherId != null">
|
|
|
+ <!-- 优化:将子查询改为EXISTS,性能更好 -->
|
|
|
+ AND EXISTS (
|
|
|
+ SELECT 1 FROM dz_teacher_class t
|
|
|
+ WHERE t.teacher_id = #{teacherId}
|
|
|
+ AND NOW() < t.out_date
|
|
|
+ AND (t.class_id = SBI.class_id OR t.class_id = SBI.campus_class_id)
|
|
|
+ )
|
|
|
+ </if>
|
|
|
<if test="classId != null"> AND SBI.class_id = #{classId}</if>
|
|
|
<if test="campusId != null"> AND SBI.campus_id = #{campusId}</if>
|
|
|
<if test="campusClassId != null"> AND SBI.campus_class_id = #{campusClassId}</if>
|