From ee80a41dd54b86685287f6c2b774c6009e4526c8 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 11 Apr 2024 13:55:19 +0100 Subject: [PATCH] MDL-74610 quiz: fix grade items query for MySQL --- .../local/reports/attempts_report_table.php | 27 +++++++------------ question/engine/datalib.php | 8 +++++- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/mod/quiz/classes/local/reports/attempts_report_table.php b/mod/quiz/classes/local/reports/attempts_report_table.php index ef318fb314d..cff27296312 100644 --- a/mod/quiz/classes/local/reports/attempts_report_table.php +++ b/mod/quiz/classes/local/reports/attempts_report_table.php @@ -671,28 +671,21 @@ abstract class attempts_report_table extends \table_sql { * @param int $gradeitemid the grade item to add information for. */ protected function add_grade_item_mark(int $gradeitemid): void { + $dm = new question_engine_data_mapper(); + $alias = 'gimarks' . $gradeitemid; - // This condition roughly filters the list of attempts to be considered. - // It is only used in a sub-select to help database query optimisers (see MDL-30122). - // Therefore, it is better to use a very simple which may include - // too many records, than to do a super-accurate join. - $qubaids = new qubaid_join("{quiz_slots} {$alias}slot2", 'quiza.uniqueid', - "{$alias}slot2.quizgradeitemid = :{$alias}gradeitemid2", [$alias . 'gradeitemid2' => $gradeitemid]); - - $dm = new question_engine_data_mapper(); - [$qalatestview, $viewparams] = $dm->question_attempt_latest_state_view($alias, $qubaids); - $this->sql->fields .= ",\n( - SELECT SUM({$alias}.fraction * {$alias}.maxmark) AS summarks + SELECT SUM({$alias}qas.fraction * {$alias}qa.maxmark) AS summarks - FROM {quiz_slots} slot - JOIN $qalatestview ON {$alias}.slot = slot.slot - - WHERE slot.quizgradeitemid = :{$alias}gradeitemid - ) marks$gradeitemid"; + FROM {quiz_slots} {$alias}slot + JOIN {question_attempts} {$alias}qa ON {$alias}qa.slot = {$alias}slot.slot + JOIN {question_attempt_steps} {$alias}qas ON {$alias}qas.questionattemptid = {$alias}qa.id + AND {$alias}qas.sequencenumber = {$dm->latest_step_for_qa_subquery("{$alias}qa.id")} + WHERE {$alias}qa.questionusageid = quiza.uniqueid + AND {$alias}slot.quizgradeitemid = :{$alias}gradeitemid + ) AS marks$gradeitemid"; $this->sql->params[$alias . 'gradeitemid'] = $gradeitemid; - $this->sql->params = array_merge($this->sql->params, $viewparams); } /** diff --git a/question/engine/datalib.php b/question/engine/datalib.php index 6481e4f9f86..723112fd88d 100644 --- a/question/engine/datalib.php +++ b/question/engine/datalib.php @@ -1252,7 +1252,13 @@ ORDER BY ) {$alias}", $qubaids->from_where_params()); } - protected function latest_step_for_qa_subquery($questionattemptid = 'qa.id') { + /** + * Get the subquery which selects the latest step for each question_attempt. + * + * @param string $questionattemptid column alias for the column to join on which is question_attempt.id. + * @return string SQL fragment to include in the query. Has not placeholders. + */ + public function latest_step_for_qa_subquery($questionattemptid = 'qa.id') { return "( SELECT MAX(sequencenumber) FROM {question_attempt_steps}