SQL-запрос для зачисления на курсы Moodle

Я искал правильные SQL-запросы для извлечения всех студентов, обучающихся на определенном курсе, или всех курсов, на которые записался определенный студент, на Moodle.

Я нашел несколько решений из интернета, и большинство из них предлагают присоединиться к этим таблицам:
контекст, role_assignments, конечно, пользователь, роль

но потом, когда я посмотрел на базу данных, я обнаружил, что есть таблица с именем user_enrolments, и мне кажется, что я можно получить результаты, присоединившись к следующим таблицам:
user_enrolments, пользователь, конечно, зачислить

например,

SELECT u.id, c.id
FROM mdl_user u
INNER JOIN mdl_user_enrolments ue ON ue.userid = u.id
INNER JOIN mdl_enrol e ON e.id = ue.enrolid
INNER JOIN mdl_course c ON e.courseid = c.id

и

SELECT u.id, c.id
FROM mdl_user u
INNER JOIN mdl_role_assignments ra ON ra.userid = u.id
INNER JOIN mdl_context ct ON ct.id = ra.contextid
INNER JOIN mdl_course c ON c.id = ct.instanceid
INNER JOIN mdl_role r ON r.id = ra.roleid
WHERE r.id = 5

(где 5-идентификатор роли student)

эти 2 запроса дают мне то же самое набор результатов. (проверено только на небольшом наборе данных)

поэтому я хотел бы спросить, каковы различия между двумя подходами?
Спасибо за любая помощь заранее.

5 ответов


первый запрос дает вам список пользователей, которые enroled на курсе, независимо от роли, которую они им назначили (можно быть enroled на курсе и не иметь никакой роли, назначенной вообще).

второй запрос показывает всех пользователей, которым назначена роль 5 на уровне курса. Можно (хотя и необычно) иметь роль, назначенную на уровне курса, не будучи фактически вовлеченным в сам курс.

однако оба запроса недостатки.

первый запрос может возвращать повторяющиеся результаты, если пользователь был включен в курс более чем одним методом зачисления (необычно, но возможно). Он также не учитывает следующее:

  • плагин приема может быть отключен на уровне сайта
  • плагин зачисления может быть отключен на уровне курса (проверьте " e.status = 0', чтобы найти только активные Плагины зачисления)
  • зачисление может быть ограничено по времени - возможно, срок регистрации пользователя истек (проверьте ' ue.timeend = 0 или ue.timeend > NOW () ' найти только неизрасходованные зачисления)

во втором запросе предполагается, что роль student имеет id 5 (а также что нет других ролей, основанных на роли student, которые используются). Обычно я либо использую дополнительный запрос для проверки идентификатора роли "student" в таблице "mdl_role", а затем использую это значение, либо изменяю последние пару строк на следующее:

Регистрация mdl_role r на r.id = ra.roleid и R.студент краткое имя =''.

второй запрос также не может проверить "contextlevel" - можно иметь несколько контекстов с одним и тем же идентификатором экземпляра (как можно иметь идентификатор курса 5, идентификатор категории курса 5, идентификатор пользователя 5 и т. д.)- поэтому вам нужно проверить, что найденный контекст является контекстом "курса" (contextlevel = 50).

ни один запрос не проверяет приостановленных или удаленных пользователей (хотя, в случае удаленных пользователей, они должны были автоматически unenroled из всех курсов, в том месте, где они были удалены).

полностью полное решение (возможно, слишком сложное для большинства ситуаций) объединило бы оба запроса вместе, чтобы проверить, что пользователь был enroled и назначен на роль студента, а не приостановлен:

SELECT DISTINCT u.id AS userid, c.id AS courseid
FROM mdl_user u
JOIN mdl_user_enrolments ue ON ue.userid = u.id
JOIN mdl_enrol e ON e.id = ue.enrolid
JOIN mdl_role_assignments ra ON ra.userid = u.id
JOIN mdl_context ct ON ct.id = ra.contextid AND ct.contextlevel = 50
JOIN mdl_course c ON c.id = ct.instanceid AND e.courseid = c.id
JOIN mdl_role r ON r.id = ra.roleid AND r.shortname = 'student'
WHERE e.status = 0 AND u.suspended = 0 AND u.deleted = 0
  AND (ue.timeend = 0 OR ue.timeend > NOW()) AND ue.status = 0

(обратите внимание, что я не дважды проверял этот запрос-он работает, но вам нужно будет тщательно перекрестно ссылаться на фактические зачисления, чтобы проверить, что я не пропустил что угодно.)


следующий код генерирует список всех ваших курсов вместе с количеством студентов, обучающихся в каждом. Полезно узнать, есть ли у вас какие-либо курсы, на которые никто не зачислен.

Мой Ответ :

SELECT cr.SHORTNAME, 
       cr.FULLNAME, 
       COUNT(ra.ID) AS enrolled 
FROM   `MDL_COURSE` cr 
       JOIN `MDL_CONTEXT` ct 
         ON ( ct.INSTANCEID = cr.ID ) 
       LEFT JOIN `MDL_ROLE_ASSIGNMENTS` ra 
              ON ( ra.CONTEXTID = ct.ID ) 
WHERE  ct.CONTEXTLEVEL = 50 
       AND ra.ROLEID = 5 
GROUP  BY cr.SHORTNAME, 
          cr.FULLNAME 
ORDER  BY `ENROLLED` ASC 

в случае необходимости в графу учащихся за курс. Это может быть достигнуто просто с помощью API регистрации. Секретный ключ здесь поставляет до count_enrolled_users() функция, которая только Student роль. Например:

$context = context_COURSE::instance($course->id);
count_enrolled_users($context,'mod/assignment:submit')

здесь mod/assignment:submit это возможность, которую может сделать только студент, поэтому возвращаемый номер int не будет включать другие общие роли, такие как учителя, зачисленные в курс.

я использовал приведенный выше код для Moodle 3.1 в теме renderer.php чтобы показать количество зачисленных студентов для каждого курса в списке курсов на первой странице.


первый запрос даст вам все, независимо от их роли-таблица используется для хранения типа зачисления -http://docs.moodle.org/26/en/Enrolment_plugins

второй даст вам только студентов-так будет полезнее.

Это те же результаты, потому что только студенты были назначены на курсы.

Если вы идете на курс и записаться пользователей. Затем в верхней части всплывающего окна выберите назначить роли = учитель и зарегистрируйте пользователя. Итак, на курсе у вас теперь будет ученик(Ы) и учитель

затем повторно запустите запросы, второй запрос будет иметь меньше результатов, потому что у него будут только студенты.


Если вы хотите получить курсы, на которые зарегистрирован отдельный пользователь...

SELECT c.id, c.shortname, c.summary, c.idnumber  
FROM mdl_course c 
JOIN mdl_enrol en ON en.courseid = c.id 
JOIN mdl_user_enrolments ue ON ue.enrolid = en.id 
WHERE ue.userid = '12345'
AND  c.idnumber LIKE "blah%"

(последняя строка является необязательной и может использоваться для фильтрации курсов определенного типа. Обратите внимание, что idnumber является необязательным и вручную редактируемые поля.)