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
является необязательным и вручную редактируемые поля.)