diff --git a/src/main/java/com/sztzjy/linkCommerce/service/ExamService.java b/src/main/java/com/sztzjy/linkCommerce/service/ExamService.java index e5398d1..78c3518 100644 --- a/src/main/java/com/sztzjy/linkCommerce/service/ExamService.java +++ b/src/main/java/com/sztzjy/linkCommerce/service/ExamService.java @@ -433,14 +433,7 @@ public class ExamService { bucket("良好", scores, total.multiply(new BigDecimal("0.80")), total.multiply(new BigDecimal("0.90"))), bucket("及格", scores, pass, total.multiply(new BigDecimal("0.80"))), bucket("不及格", scores, BigDecimal.ZERO, pass)); - String hardestSql = "select p.question_id id,p.stem,p.question_score, count(distinct t.id) student_count, " + - "sum(case when coalesce(a.awarded_score,0) < p.question_score then 1 else 0 end) wrong_count, " + - "coalesce(sum(coalesce(a.awarded_score,0)),0) earned_score " + - "from exam_assessment_question p join exam_attempt t on t.exam_id=p.exam_id and t.attempt_status='SUBMITTED' " + - "left join exam_attempt_answer a on a.attempt_id=t.id and a.question_id=p.question_id " + - "where p.exam_id=?" + (StringUtils.isBlank(classId) ? "" : " and t.teaching_class_id=? ") + - "group by p.question_id,p.stem,p.question_score " + - "order by (case when count(distinct t.id)=0 then 100 else coalesce(sum(coalesce(a.awarded_score,0)),0) * 100.0 / (count(distinct t.id) * p.question_score) end) asc, wrong_count desc limit 3"; + String hardestSql = analysisHardestSql(StringUtils.isNotBlank(classId)); List> hardest = jdbc.query(hardestSql, (rs, n) -> { int students = rs.getInt("student_count"); @@ -754,6 +747,17 @@ public class ExamService { if (!expected.equals(actual)) throw new IllegalArgumentException(message); } + static String analysisHardestSql(boolean withClassFilter) { + return "select p.question_id id,p.stem,p.question_score, count(distinct t.id) student_count, " + + "sum(case when coalesce(a.awarded_score,0) < p.question_score then 1 else 0 end) wrong_count, " + + "coalesce(sum(coalesce(a.awarded_score,0)),0) earned_score " + + "from exam_assessment_question p join exam_attempt t on t.exam_id=p.exam_id and t.attempt_status='SUBMITTED' " + + "left join exam_attempt_answer a on a.attempt_id=t.id and a.question_id=p.question_id " + + "where p.exam_id=? " + (withClassFilter ? "and t.teaching_class_id=? " : "") + + "group by p.question_id,p.stem,p.question_score " + + "order by (case when count(distinct t.id)=0 then 100 else coalesce(sum(coalesce(a.awarded_score,0)),0) * 100.0 / (count(distinct t.id) * p.question_score) end) asc, wrong_count desc limit 3"; + } + static void validateDelete(String status, Object exportedAt) { if ("DRAFT".equals(status)) return; requireState(status, "ENDED", "只有未发布或已结束的考试可以删除"); diff --git a/src/test/java/com/sztzjy/linkCommerce/service/ExamServiceTest.java b/src/test/java/com/sztzjy/linkCommerce/service/ExamServiceTest.java index c929c07..6a78825 100644 --- a/src/test/java/com/sztzjy/linkCommerce/service/ExamServiceTest.java +++ b/src/test/java/com/sztzjy/linkCommerce/service/ExamServiceTest.java @@ -58,6 +58,15 @@ class ExamServiceTest { } } + @Test + void analysisHardestSqlKeepsParameterAndGroupBySeparated() { + for (String sql : Arrays.asList(ExamService.analysisHardestSql(false), ExamService.analysisHardestSql(true))) { + assertFalse(sql.contains("?group")); + assertTrue(sql.contains("? group by p.question_id")); + } + assertTrue(ExamService.analysisHardestSql(true).contains("? and t.teaching_class_id=? group by")); + } + @Test void studentAnswerFilesStillRejectExcel() { IllegalArgumentException error = assertThrows(IllegalArgumentException.class,